Skip to content

Ignore Range header if served file is 0 bytes#2159

Merged
ioquatix merged 1 commit into
rack:mainfrom
zarqman:ignore-range-for-empty-files
Feb 26, 2024
Merged

Ignore Range header if served file is 0 bytes#2159
ioquatix merged 1 commit into
rack:mainfrom
zarqman:ignore-range-for-empty-files

Conversation

@zarqman

@zarqman zarqman commented Feb 25, 2024

Copy link
Copy Markdown
Contributor

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
Copy Markdown
Member

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

@jeremyevans jeremyevans left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems fine to me.

@ioquatix ioquatix left a comment

Copy link
Copy Markdown
Member

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!

Comment thread lib/rack/utils.rb
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 zarqman force-pushed the ignore-range-for-empty-files branch from de2687b to a7be570 Compare February 26, 2024 05:21
@zarqman

zarqman commented Feb 26, 2024

Copy link
Copy Markdown
Contributor Author

Changelog and comment both added.

@ioquatix ioquatix merged commit dff6cfd into rack:main Feb 26, 2024
@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.

3 participants