if-range issue

Anatoli Marinov a.marinov at ucdn.com
Wed Aug 13 11:17:04 UTC 2014


The patch change the behavior for more liberal direction :)


On Wed, Aug 13, 2014 at 2:08 PM, Anatoli Marinov <a.marinov at ucdn.com> wrote:

> I know this, but I used nginx as a reverse proxy and Etag comes from
> remote server through nginx upstream. In general I do not have any control
> on its value. Nginx uses this value as it is sent from the other server.
> The file is cached with it and also this value is send to all http clients.
>
>
> On Wed, Aug 13, 2014 at 1:22 PM, Roman Arutyunyan <arut at nginx.com> wrote:
>
>> 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
>>
>> _______________________________________________
>> nginx-devel mailing list
>> nginx-devel at nginx.org
>> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20140813/50a9971c/attachment-0001.html>


More information about the nginx-devel mailing list