summary refs log tree commit
diff options
context:
space:
mode:
authorJames Tucker <jftucker@gmail.com>2014-07-18 12:05:14 -0700
committerJames Tucker <jftucker@gmail.com>2014-07-18 12:05:14 -0700
commitaf68941bd0e1e2e58dcdc53f9191eefe32fb67fb (patch)
treebf0b4032c8726de22c7dca3fe193b0099af0419e
parent96fd002b917ac504e2416f48d280c02538e54b03 (diff)
parentf2cbe32a1dd1863dd68fea79905acf4dad8a2c5f (diff)
downloadrack-af68941bd0e1e2e58dcdc53f9191eefe32fb67fb.tar.gz
Merge pull request #710 from rack/webrick-chunking
Monkey patch to fix WEBrick chunking semantics.
-rw-r--r--lib/rack/handler/webrick.rb18
-rw-r--r--test/spec_webrick.rb18
2 files changed, 36 insertions, 0 deletions
diff --git a/lib/rack/handler/webrick.rb b/lib/rack/handler/webrick.rb
index f76679b4..023d8b27 100644
--- a/lib/rack/handler/webrick.rb
+++ b/lib/rack/handler/webrick.rb
@@ -2,6 +2,23 @@ require 'webrick'
 require 'stringio'
 require 'rack/content_length'
 
+# This monkey patch allows for applications to perform their own chunking
+# through WEBrick::HTTPResponse iff rack is set to true.
+class WEBrick::HTTPResponse
+  attr_accessor :rack
+
+  alias _rack_setup_header setup_header
+  def setup_header
+    app_chunking = rack && @header['transfer-encoding'] == 'chunked'
+
+    @chunked = app_chunking if app_chunking
+
+    _rack_setup_header
+
+    @chunked = false if app_chunking
+  end
+end
+
 module Rack
   module Handler
     class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
@@ -39,6 +56,7 @@ module Rack
       end
 
       def service(req, res)
+        res.rack = true
         env = req.meta_vars
         env.delete_if { |k, v| v.nil? }
 
diff --git a/test/spec_webrick.rb b/test/spec_webrick.rb
index b29a82d5..497bfe20 100644
--- a/test/spec_webrick.rb
+++ b/test/spec_webrick.rb
@@ -162,5 +162,23 @@ describe Rack::Handler::WEBrick do
     }
   end
 
+  should "produce correct HTTP semantics with and without app chunking" do
+    @server.mount "/chunked", Rack::Handler::WEBrick,
+    Rack::Lint.new(lambda{ |req|
+      [
+        200,
+        {"Transfer-Encoding" => "chunked"},
+        ["7\r\nchunked\r\n0\r\n\r\n"]
+      ]
+    })
+
+    Net::HTTP.start(@host, @port){ |http|
+      res = http.get("/chunked")
+      res["Transfer-Encoding"].should.equal "chunked"
+      res["Content-Length"].should.equal nil
+      res.body.should.equal "chunked"
+    }
+  end
+
   @server.shutdown
 end