Browse files

Better Content-Length handling for HEAD requests

Responses to HEAD requests _should_ have a Content-Length header
that's identical to GET requests. When a body is provided by the
application, set the Content-Length header to the size of the body
and replace the body with an empty Array; when no body is provided
by the application in response to a HEAD request, and the
Content-Length is calculated to be "0", remove the Content-Length
header entirely to avoid mis-matched values.

The idea here is that it's better to omit the header when we believe
the Content-Length is not indicative of the same in response to GET
than to send the Content-Length with a mismatched value. Logic
taken from Apache and is generally in line with RFC 2616.
  • Loading branch information...
1 parent 7196ea4 commit 98427cefa73c898f58c7a4a45af855e241f1688b @rtomayko rtomayko committed Feb 25, 2009
Showing with 11 additions and 3 deletions.
  1. +9 −2 lib/sinatra/base.rb
  2. +2 −1 test/test_test.rb
11 lib/sinatra/base.rb
@@ -344,9 +344,16 @@ def call!(env)
invoke { dispatch! }
invoke { error_block!(response.status) }
- # never respond with a body on HEAD requests
status, header, body = @response.finish
- body = [] if @env['REQUEST_METHOD'] == 'HEAD'
+ # Never produce a body on HEAD requests. Do retain the Content-Length
+ # unless it's "0", in which case we assume it was calculated erroneously
+ # for a manual HEAD response and remove it entirely.
+ if @env['REQUEST_METHOD'] == 'HEAD'
+ body = []
+ header.delete('Content-Length') if header['Content-Length'] == '0'
+ end
[status, header, body]
3 test/test_test.rb
@@ -45,7 +45,8 @@ def request_params
assert_equal('DELETE', request['REQUEST_METHOD'])
head '/'
- assert_equal('0', headers['Content-Length'])
+ assert_equal('596', response.headers['Content-Length'])
+ assert_equal('', response.body)
it 'allows to specify a body' do

0 comments on commit 98427ce

Please sign in to comment.