Skip to content
This repository
Browse code

Merge pull request #533 from dahakawang/master

add partial rack hijack for WEBrick
  • Loading branch information...
commit 232ed1ee3a2620e717a603319e52aa82d687554b 2 parents 7b535cd + 146614c
Konstantin Haase authored March 29, 2013
24  lib/rack/handler/webrick.rb
@@ -8,6 +8,7 @@ class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
8 8
       def self.run(app, options={})
9 9
         options[:BindAddress] = options.delete(:Host) if options[:Host]
10 10
         options[:Port] ||= 8080
  11
+        options[:OutputBufferSize] = 5
11 12
         @server = ::WEBrick::HTTPServer.new(options)
12 13
         @server.mount "/", Rack::Handler::WEBrick, app
13 14
         yield @server  if block_given?
@@ -46,7 +47,11 @@ def service(req, res)
46 47
                      "rack.multiprocess" => false,
47 48
                      "rack.run_once" => false,
48 49
 
49  
-                     "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
  50
+                     "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http",
  51
+
  52
+                     "rack.hijack?" => true,
  53
+                     "rack.hijack" => lambda { raise NotImplementedError, "only partial hijack is supported."},
  54
+                     "rack.hijack_io" => nil,
50 55
                    })
51 56
 
52 57
         env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
@@ -61,6 +66,8 @@ def service(req, res)
61 66
         begin
62 67
           res.status = status.to_i
63 68
           headers.each { |k, vs|
  69
+            next if k.downcase == "rack.hijack"
  70
+
64 71
             if k.downcase == "set-cookie"
65 72
               res.cookies.concat vs.split("\n")
66 73
             else
@@ -69,9 +76,18 @@ def service(req, res)
69 76
               res[k] = vs.split("\n").join(", ")
70 77
             end
71 78
           }
72  
-          body.each { |part|
73  
-            res.body << part
74  
-          }
  79
+
  80
+          io_lambda = headers["rack.hijack"]
  81
+          if io_lambda
  82
+            rd, wr = IO.pipe
  83
+            res.body = rd
  84
+            res.chunked = true
  85
+            io_lambda.call wr
  86
+          else
  87
+            body.each { |part|
  88
+              res.body << part
  89
+            }
  90
+          end
75 91
         ensure
76 92
           body.close  if body.respond_to? :close
77 93
         end
23  test/spec_webrick.rb
@@ -139,5 +139,28 @@
139 139
     }
140 140
   end
141 141
 
  142
+  should "support Rack partial hijack" do
  143
+    io_lambda = lambda{ |io|
  144
+      5.times do
  145
+        io.write "David\r\n"
  146
+      end
  147
+      io.close
  148
+    }
  149
+
  150
+    @server.mount "/partial", Rack::Handler::WEBrick,
  151
+    Rack::Lint.new(lambda{ |req|
  152
+      [
  153
+        200,
  154
+        {"rack.hijack" => io_lambda},
  155
+        [""]
  156
+      ]
  157
+    })
  158
+
  159
+    Net::HTTP.start(@host, @port){ |http|
  160
+      res = http.get("/partial")
  161
+      res.body.should.equal "David\r\nDavid\r\nDavid\r\nDavid\r\nDavid\r\n"
  162
+    }
  163
+  end
  164
+
142 165
   @server.shutdown
143 166
 end

0 notes on commit 232ed1e

Please sign in to comment.
Something went wrong with that request. Please try again.