Skip to content

Commit

Permalink
Merge pull request rack#533 from dahakawang/master
Browse files Browse the repository at this point in the history
add partial rack hijack for WEBrick
  • Loading branch information
rkh committed Mar 29, 2013
2 parents 7b535cd + 146614c commit 232ed1e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
24 changes: 20 additions & 4 deletions lib/rack/handler/webrick.rb
Expand Up @@ -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?
Expand Down Expand Up @@ -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"]
Expand All @@ -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
Expand All @@ -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
Expand Down
23 changes: 23 additions & 0 deletions test/spec_webrick.rb
Expand Up @@ -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

0 comments on commit 232ed1e

Please sign in to comment.