mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Add support for the rack hijack protocol
This commit is contained in:
parent
804a6e2c20
commit
daa76a1e90
6 changed files with 51 additions and 7 deletions
|
@ -36,14 +36,22 @@ module Puma
|
||||||
@timeout_at = nil
|
@timeout_at = nil
|
||||||
|
|
||||||
@requests_served = 0
|
@requests_served = 0
|
||||||
|
@hijacked = false
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :env, :to_io, :body, :io, :timeout_at, :ready
|
attr_reader :env, :to_io, :body, :io, :timeout_at, :ready, :hijacked
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
"#<Puma::Client:0x#{object_id.to_s(16)} @ready=#{@ready.inspect}>"
|
"#<Puma::Client:0x#{object_id.to_s(16)} @ready=#{@ready.inspect}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# For the hijack protocol (allows us to just put the Client object
|
||||||
|
# into the env)
|
||||||
|
def call
|
||||||
|
@hijacked = true
|
||||||
|
env[HIJACK_IO] ||= @io
|
||||||
|
end
|
||||||
|
|
||||||
def set_timeout(val)
|
def set_timeout(val)
|
||||||
@timeout_at = Time.now + val
|
@timeout_at = Time.now + val
|
||||||
end
|
end
|
||||||
|
|
|
@ -147,5 +147,9 @@ module Puma
|
||||||
COLON = ": ".freeze
|
COLON = ": ".freeze
|
||||||
|
|
||||||
NEWLINE = "\n".freeze
|
NEWLINE = "\n".freeze
|
||||||
|
|
||||||
|
HIJACK_P = "rack.hijack?".freeze
|
||||||
|
HIJACK = "rack.hijack".freeze
|
||||||
|
HIJACK_IO = "rack.hijack_io".freeze
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -332,6 +332,9 @@ module Puma
|
||||||
|
|
||||||
env[PUMA_SOCKET] = client
|
env[PUMA_SOCKET] = client
|
||||||
|
|
||||||
|
env[HIJACK_P] = true
|
||||||
|
env[HIJACK] = req
|
||||||
|
|
||||||
body = req.body
|
body = req.body
|
||||||
|
|
||||||
env[RACK_INPUT] = body
|
env[RACK_INPUT] = body
|
||||||
|
@ -345,6 +348,9 @@ module Puma
|
||||||
begin
|
begin
|
||||||
begin
|
begin
|
||||||
status, headers, res_body = @app.call(env)
|
status, headers, res_body = @app.call(env)
|
||||||
|
|
||||||
|
return :async if req.hijacked
|
||||||
|
|
||||||
status = status.to_i
|
status = status.to_i
|
||||||
|
|
||||||
if status == -1
|
if status == -1
|
||||||
|
@ -406,6 +412,8 @@ module Puma
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
response_hijack = nil
|
||||||
|
|
||||||
headers.each do |k, vs|
|
headers.each do |k, vs|
|
||||||
case k
|
case k
|
||||||
when CONTENT_LENGTH2
|
when CONTENT_LENGTH2
|
||||||
|
@ -416,6 +424,9 @@ module Puma
|
||||||
content_length = nil
|
content_length = nil
|
||||||
when CONTENT_TYPE
|
when CONTENT_TYPE
|
||||||
next if no_body
|
next if no_body
|
||||||
|
when HIJACK
|
||||||
|
response_hijack = vs
|
||||||
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
vs.split(NEWLINE).each do |v|
|
vs.split(NEWLINE).each do |v|
|
||||||
|
@ -435,6 +446,7 @@ module Puma
|
||||||
lines << CONNECTION_CLOSE
|
lines << CONNECTION_CLOSE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless response_hijack
|
||||||
if content_length
|
if content_length
|
||||||
lines.append CONTENT_LENGTH_S, content_length.to_s, line_ending
|
lines.append CONTENT_LENGTH_S, content_length.to_s, line_ending
|
||||||
chunked = false
|
chunked = false
|
||||||
|
@ -442,11 +454,17 @@ module Puma
|
||||||
lines << TRANSFER_ENCODING_CHUNKED
|
lines << TRANSFER_ENCODING_CHUNKED
|
||||||
chunked = true
|
chunked = true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
lines << line_ending
|
lines << line_ending
|
||||||
|
|
||||||
fast_write client, lines.to_s
|
fast_write client, lines.to_s
|
||||||
|
|
||||||
|
if response_hijack
|
||||||
|
response_hijack.call client
|
||||||
|
return :async
|
||||||
|
end
|
||||||
|
|
||||||
res_body.each do |part|
|
res_body.each do |part|
|
||||||
if chunked
|
if chunked
|
||||||
client.syswrite part.bytesize.to_s(16)
|
client.syswrite part.bytesize.to_s(16)
|
||||||
|
|
3
test/hello-delay.ru
Normal file
3
test/hello-delay.ru
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello World"]] }
|
6
test/hijack.ru
Normal file
6
test/hijack.ru
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
run lambda { |env|
|
||||||
|
io = env['rack.hijack'].call
|
||||||
|
io.puts "HTTP/1.1 200\r\n\r\nBLAH"
|
||||||
|
[-1, {}, []]
|
||||||
|
}
|
5
test/hijack2.ru
Normal file
5
test/hijack2.ru
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
run lambda { |env|
|
||||||
|
body = lambda { |io| io.puts "BLAH\n"; io.close }
|
||||||
|
|
||||||
|
[200, { 'rack.hijack' => body }, []]
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue