Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore Range header if served file is 0 bytes #2159

Merged
merged 1 commit into from Feb 26, 2024

Conversation

zarqman
Copy link
Contributor

@zarqman zarqman commented Feb 25, 2024

Normally Rack::Files truncates a byte range to fit a file's contents--as long as at least some bytes are within range. However, an empty (0 byte) file is a special case since there are no requested bytes that can be within range.

Previously, 0 byte files requested with a Range header always resulted in a 416 error. This PR changes 0 byte files to ignore the Range header and return the empty file.

Ignoring the Range header is allowed per RFC 9110 §14.2.

This improves compatibility with clients that speculatively request files with byte ranges. For example, Nginx's slice / slice_range feature causes all requests to utilize Range.

Slightly ironically, this also results in a smaller response. (On this basis, it could even be argued to ignore Range for files below 50-100 bytes.)

Before

$ curl -i -H 'Range: bytes=0-1023' http://localhost:3000/favicon.ico
HTTP/1.1 416 Range Not Satisfiable
content-type: image/vnd.microsoft.icon
x-cascade: pass
content-range: bytes */0
Content-Length: 25

Byte range unsatisfiable

After

$ curl -i -H 'Range: bytes=0-1023' http://localhost:3000/favicon.ico
HTTP/1.1 200 OK
last-modified: Tue, 15 Jan 2019 21:51:01 GMT
content-type: image/vnd.microsoft.icon
Content-Length: 0

@ioquatix
Copy link
Member

This seems reasonable to me, @jeremyevans @tenderlove do you have any thoughts or potential security issues?

Copy link
Contributor

@jeremyevans jeremyevans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me.

Copy link
Member

@ioquatix ioquatix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. Can you please:

  • Add an entry to the changelog.

Thanks!

lib/rack/utils.rb Show resolved Hide resolved
Normally Rack::Files truncates a byte range to fit a file's contents as long as
at least some bytes are within range. However, an empty (0 byte) file is a
special case. Previously, empty files requested with a Range header always
resulted in a 416 error. This changes 0 byte files to ignore the Range header
and return the empty file.

This improves compatibility with clients that speculatively request files with
byte ranges.
@zarqman
Copy link
Contributor Author

zarqman commented Feb 26, 2024

Changelog and comment both added.

@ioquatix ioquatix merged commit dff6cfd into rack:main Feb 26, 2024
15 of 16 checks passed
@zarqman zarqman deleted the ignore-range-for-empty-files branch February 28, 2024 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants