diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-11-12 20:58:46 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-11-12 20:58:46 +0000 |
commit | fd3b5312625f06baeda726ef4b32e7a3ac336698 (patch) | |
tree | e0e077d715a699bf60482eab5353f324915642a5 | |
parent | df1506b0825a096514fcb3821563bf9e8fd52743 (diff) | |
download | rack-ancient-chunked.tar.gz |
chunked: do not chunk on pre-HTTP/1.0 clients ancient-chunked
Ancient HTTP clients which predate HTTP/1.0 may not set HTTP_VERSION at all, and those do not support chunking. RFC 1945 describes HTTP/0.9 as well as HTTP/1.0
-rw-r--r-- | lib/rack/chunked.rb | 13 | ||||
-rw-r--r-- | test/spec_chunked.rb | 16 |
2 files changed, 28 insertions, 1 deletions
diff --git a/lib/rack/chunked.rb b/lib/rack/chunked.rb index a400756a..ea221fa9 100644 --- a/lib/rack/chunked.rb +++ b/lib/rack/chunked.rb @@ -39,11 +39,22 @@ module Rack @app = app end + # pre-HTTP/1.0 (informally "HTTP/0.9") HTTP requests did not have + # a version (nor response headers) + def chunkable_version?(ver) + case ver + when "HTTP/1.0", nil, "HTTP/0.9" + false + else + true + end + end + def call(env) status, headers, body = @app.call(env) headers = HeaderHash.new(headers) - if env['HTTP_VERSION'] == 'HTTP/1.0' || + if ! chunkable_version?(env['HTTP_VERSION']) || STATUS_WITH_NO_ENTITY_BODY.include?(status) || headers['Content-Length'] || headers['Transfer-Encoding'] diff --git a/test/spec_chunked.rb b/test/spec_chunked.rb index 12f21581..0a6d9ff1 100644 --- a/test/spec_chunked.rb +++ b/test/spec_chunked.rb @@ -64,6 +64,22 @@ describe Rack::Chunked do body.join.should.equal 'Hello World!' end + should 'not modify response when client is ancient, pre-HTTP/1.0' do + app = lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hello', ' ', 'World!']] } + check = lambda do + status, headers, body = chunked(app).call(@env.dup) + status.should.equal 200 + headers.should.not.include 'Transfer-Encoding' + body.join.should.equal 'Hello World!' + end + + @env.delete('HTTP_VERSION') # unicorn will do this on pre-HTTP/1.0 requests + check.call + + @env['HTTP_VERSION'] = 'HTTP/0.9' # not sure if this happens in practice + check.call + end + should 'not modify response when Transfer-Encoding header already present' do app = lambda { |env| [200, {"Content-Type" => "text/plain", 'Transfer-Encoding' => 'identity'}, ['Hello', ' ', 'World!']] |