#1971 closed defect (invalid)
Invalid 200 (OK) response code to range request
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.19.x |
Keywords: | ranged request | Cc: | |
uname -a: | Linux 4.4.0-70-generic #91~14.04.1-Ubuntu SMP Wed Mar 22 15:48:21 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.14.0
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4) built with OpenSSL 1.0.1f 6 Jan 2014 TLS SNI support enabled |
Description
Observed behaviour: nginx responds with 200 (OK) to 0-10 ranged request for empty file.
Relevant part of nginx configuration file:
server { listen localhost:9998 backlog=65536 deferred reuseport; autoindex on; root ~/nginx_tests/files; location / { } }
Steps to reproduce:
~/nginx_tests$ touch files/empty.txt ~/nginx_tests$ curl http://localhost:9998/empty.txt -i -H "Range: bytes=0-10" HTTP/1.1 200 OK Server: nginx/1.14.0 Date: Thu, 07 May 2020 08:00:22 GMT Content-Type: text/plain Content-Length: 0 Last-Modified: Thu, 07 May 2020 08:00:07 GMT Connection: keep-alive ETag: "5eb3c007-0" Accept-Ranges: bytes
Expected behaviour: According to https://tools.ietf.org/html/rfc7233#section-2.1, nginx was expected to return 416 (Range Not Satisfiable):
If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that is less than the current length of the representation, or at least one suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set is satisfiable. **Otherwise, the byte-range-set is unsatisfiable.**
Possibly related nginx source code:
Because the code adjusts parsed end
value with content size here: https://trac.nginx.org/nginx/browser/nginx/src/http/modules/ngx_http_range_filter_module.c#L363
It mistakenly decides that parsed range is invalid and returns NGX_DECLINED
here: https://trac.nginx.org/nginx/browser/nginx/src/http/modules/ngx_http_range_filter_module.c#L391
The code then handles valid ranged request as invalid here: https://trac.nginx.org/nginx/browser/nginx/src/http/modules/ngx_http_range_filter_module.c#L249
Change History (3)
comment:1 by , 5 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 5 years ago
Frankly, this is a weird approach to use "...may ignore..." clause only in subset of valid requests. Its clear that the request is valid. It also is clear that the valid request can not be satisfied. Why returning 200? Because it simplifies some cases? Well it complicates some cases too, otherwise I would not report this... :)
comment:3 by , 5 years ago
Any valid client is expected to handle 200 anyway, as servers are not required to support range requests, so returning 200 for empty files is expected to simplify more cases than it complicates.
Note well that nginx may (and will) return 200 in various other cases, such as when more than max_ranges ranges are requested, or total length of requested ranges is larger than the length of the file. Not to mention non-static resources, where range support is usually not available at all.
As per RFC 7233, Section 3.1, "A server MAY ignore the Range header field". This is what nginx does when a range requested from an empty file. That is, the behaviour is perfectly valid as per HTTP specification.
For reasons why nginx behaves this way please see changeset aeaac3ccee4f and ticket #1031. In short, this is perfectly valid behaviour and simplifies at least some cases, as seen with the slice module.