if-range issue

Roman Arutyunyan arut at nginx.com
Wed Aug 13 10:22:14 UTC 2014


Hello,

Etag value must be a quoted string.  Please add double quotes to
ETag and If-Range arguments and try again.

RFC7232 / Section 2.3

     ETag       = entity-tag

     entity-tag = [ weak ] opaque-tag
     weak       = %x57.2F ; "W/", case-sensitive
     opaque-tag = DQUOTE *etagc DQUOTE
     etagc      = %x21 / %x23-7E / obs-text
                ; VCHAR except double quotes, plus obs-text

On 13 Aug 2014, at 13:24, Anatoli Marinov <a.marinov at ucdn.com> wrote:

> 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 at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel



More information about the nginx-devel mailing list