<div dir="ltr"><div><div><div><div><div>Hello colleagues, <br></div>Yesterday I found an issue with latest chrome and nginx 1.6.0.<br></div>For the following request nginx returns 200 OK instead of 206 partial response:<br>
<br>REQUEST<br>GET /test.mp4 HTTP/1.1
<br>Range: bytes=53037809-53037867
<br>User-Agent: curl/7.33.0
<br>Host: <a href="http://mydomain.com">mydomain.com</a>
<br>Accept: */*
<br>If-Range: 99f71760accc95bbdeadece7a87f507a
<br><br>RESPONSE
<br>HTTP/1.1 200 OK
<br>Server: nginx
<br>Date: Wed, 13 Aug 2014 09:09:18 GMT
<br>Content-Type: video/mp4
<br>Content-Length: 53037868
<br>Connection: keep-alive
<br>Keep-Alive: timeout=150
<br>Last-Modified: Fri, 30 May 2014 00:54:47 GMT
<br>Etag: 99f71760accc95bbdeadece7a87f507a
<br>Expires: Fri, 15 Aug 2014 15:22:31 GMT
<br>Cache-Control: max-age=360000
<br>Accept-Ranges: bytes
<br><br></div>For this request nginx should return partial response with just a few bytes (58).<br></div>In general Etag and If-Range are equal and there and the range request should be satisfied.<br></div>I thing in the file ngx_http_range_filter_module.c there is wrong comparation. <br>
<div><br></div><div>This check:<br>    if (r->headers_in.if_range) {<br><br>        if_range = &r->headers_in.if_range->value;<br><br>        if (if_range->len >= 2 && if_range->data[if_range->len - 1] == '"') {<br>
<br>            if (r->headers_out.etag == NULL) {<br>                goto next_filter;<br>            }<br><br>            etag = &r->headers_out.etag->value;<br><br>            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,<br>
                           "http ir:%V etag:%V", if_range, etag);<br><br>            if (if_range->len != etag->len<br>                || ngx_strncmp(if_range->data, etag->data, etag->len) != 0)<br>
            {<br>                goto next_filter;<br>            }<br><br>            goto parse;<br>        }<br><br>        if (r->headers_out.last_modified_time == (time_t) -1) {<br>            goto next_filter;<br>
        }<br><br>        if_range_time = ngx_http_parse_time(if_range->data, if_range->len);<br><br>        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,<br>                       "http ir:%d lm:%d",<br>
                       if_range_time, r->headers_out.last_modified_time);<br><br>        if (if_range_time != r->headers_out.last_modified_time) {<br>            goto next_filter;<br>        }<br>    }<br><br><br><br>
------------------------------------------------------------------------------------------------------------------------<br><br><br><br></div><div>Should be replaced with this:<br>    if (r->headers_in.if_range) {<br><br>
        if_range = &r->headers_in.if_range->value;<br><br>        if (r->headers_out.etag) {<br>            etag = &r->headers_out.etag->value;<br><br>            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,<br>
                           "http ir:%V etag:%V", if_range, etag);<br><br>            if (if_range->len == etag->len<br>                && ngx_strncmp(if_range->data, etag->data, etag->len) == 0) {<br>
                goto parse;<br>            }<br>        }<br><br>        if (r->headers_out.last_modified_time != (time_t) -1) {<br>            if_range_time = ngx_http_parse_time(if_range->data, if_range->len);<br>
<br>            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,<br>                           "http ir:%d lm:%d",<br>                           if_range_time, r->headers_out.last_modified_time);<br>
<br>            if (if_range_time == r->headers_out.last_modified_time) {<br>                goto parse;<br>            }<br>        }<br><br>        goto next_filter;<br>    }<br></div><div><div><br></div><div>The new code is simpler and it implements the standard instead the old one.<br>
</div><div>Please comment my proposition.<br><br></div><div>Anatoli Marinov<br></div><div><br></div></div></div>