Answer HEAD from the file's size when send_file would send it as it is - #815
Merged
Conversation
HeadRequestHandler learns Content-Length by producing the body into a counting sink, so a HEAD on a 20 GB download read all 20 GB to discard them. When the stored bytes go out unchanged - no on-the-fly compression, or a pre-compressed neighbour already standing in - the length is the file's own, so send_file sets it and returns. The file is still opened so a HEAD fails exactly where the GET would; a body that gets compressed is still produced, since its length is only known afterwards. Refs #803
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The "separate" half of #803.
Description of the Change
HeadRequestHandlerswaps the response output for a countingNullIOand runs theGEThandler;Content-Lengthis whatever got written. Forsend_filethat means aHEADon a 20 GB file reads 20 GB off disk to count them. Measured with/proc/self/ioon a 50 MiB file:HEADread 50.0 MiB.When the stored bytes go out as they are —
coding.nil?, i.e. no on-the-fly compression, which also covers the pre-compressed.gzneighbourStaticFileHandlersubstitutes — the length isFile.info.size, already in hand.send_filenow setsContent-Lengthand returns before opening the body for copying. After: 0.0001 MiB read.Two deliberate limits:
File.open(file_path) { }, no read). AHEADhas to fail where theGETfails; otherwise it would report200and the size of a file theGETanswers404for (Report an unreadable static file as 404, as the stdlib does #799). Oneopen/closesyscall, no bytes.head_request_handler_spec.cr:25pins that a gzipHEADreports the compressed length. Unchanged.Verification
HEADon a 4 MiB file →200, empty body,Content-Length: 4194304(portable)./proc/self/io): theHEADreads under 1 MiB. Fails on master with 4194402 bytes read.HEADon a mode-000 file is404like theGET.-Dwithout_zlibgreen (467), ameba and format clean.