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