Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #533 from dahakawang/master

add partial rack hijack for WEBrick
  • Loading branch information...
commit 232ed1ee3a2620e717a603319e52aa82d687554b 2 parents 7b535cd + 146614c
@rkh rkh authored
Showing with 43 additions and 4 deletions.
  1. +20 −4 lib/rack/handler/webrick.rb
  2. +23 −0 test/spec_webrick.rb
View
24 lib/rack/handler/webrick.rb
@@ -8,6 +8,7 @@ class WEBrick < ::WEBrick::HTTPServlet::AbstractServlet
def self.run(app, options={})
options[:BindAddress] = options.delete(:Host) if options[:Host]
options[:Port] ||= 8080
+ options[:OutputBufferSize] = 5
@server = ::WEBrick::HTTPServer.new(options)
@server.mount "/", Rack::Handler::WEBrick, app
yield @server if block_given?
@@ -46,7 +47,11 @@ def service(req, res)
"rack.multiprocess" => false,
"rack.run_once" => false,
- "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
+ "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http",
+
+ "rack.hijack?" => true,
+ "rack.hijack" => lambda { raise NotImplementedError, "only partial hijack is supported."},
+ "rack.hijack_io" => nil,
})
env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
@@ -61,6 +66,8 @@ def service(req, res)
begin
res.status = status.to_i
headers.each { |k, vs|
+ next if k.downcase == "rack.hijack"
+
if k.downcase == "set-cookie"
res.cookies.concat vs.split("\n")
else
@@ -69,9 +76,18 @@ def service(req, res)
res[k] = vs.split("\n").join(", ")
end
}
- body.each { |part|
- res.body << part
- }
+
+ io_lambda = headers["rack.hijack"]
+ if io_lambda
+ rd, wr = IO.pipe
+ res.body = rd
+ res.chunked = true
+ io_lambda.call wr
+ else
+ body.each { |part|
+ res.body << part
+ }
+ end
ensure
body.close if body.respond_to? :close
end
View
23 test/spec_webrick.rb
@@ -139,5 +139,28 @@
}
end
+ should "support Rack partial hijack" do
+ io_lambda = lambda{ |io|
+ 5.times do
+ io.write "David\r\n"
+ end
+ io.close
+ }
+
+ @server.mount "/partial", Rack::Handler::WEBrick,
+ Rack::Lint.new(lambda{ |req|
+ [
+ 200,
+ {"rack.hijack" => io_lambda},
+ [""]
+ ]
+ })
+
+ Net::HTTP.start(@host, @port){ |http|
+ res = http.get("/partial")
+ res.body.should.equal "David\r\nDavid\r\nDavid\r\nDavid\r\nDavid\r\n"
+ }
+ end
+
@server.shutdown
end
Please sign in to comment.
Something went wrong with that request. Please try again.