mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-08-10 00:01:27 -04:00
fixed: session hangs when HTTP/2 receives a 421
While adding a test, a bug was found, where an HTTP/2 connection receiving a 421 response wasn't redirecting the request well to an HTTP/1.1 one. This has been fixed by changing the way a new connection is instantiated.
This commit is contained in:
parent
322aa06f22
commit
7f9e68ba3b
@ -120,8 +120,8 @@ module HTTPX
|
||||
end
|
||||
end
|
||||
|
||||
def create_idle
|
||||
self.class.new(@type, @origin, @options)
|
||||
def create_idle(options = {})
|
||||
self.class.new(@type, @origin, @options.merge(options))
|
||||
end
|
||||
|
||||
def merge(connection)
|
||||
@ -131,17 +131,6 @@ module HTTPX
|
||||
end
|
||||
end
|
||||
|
||||
def unmerge(connection)
|
||||
@origins -= connection.instance_variable_get(:@origins)
|
||||
purge_pending do |request|
|
||||
request.uri.origin == connection.origin && begin
|
||||
request.transition(:idle)
|
||||
connection.send(request)
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def purge_pending(&block)
|
||||
pendings = []
|
||||
if @parser
|
||||
@ -399,7 +388,7 @@ module HTTPX
|
||||
parser.on(:error) do |request, ex|
|
||||
case ex
|
||||
when MisdirectedRequestError
|
||||
emit(:uncoalesce, request.uri)
|
||||
emit(:misdirected, request)
|
||||
else
|
||||
response = ErrorResponse.new(request, ex, @options)
|
||||
request.emit(:response, response)
|
||||
|
@ -77,10 +77,16 @@ module HTTPX
|
||||
end
|
||||
|
||||
def set_connection_callbacks(connection, connections, options)
|
||||
connection.on(:uncoalesce) do |uncoalesced_uri|
|
||||
other_connection = build_connection(uncoalesced_uri, options)
|
||||
connection.on(:misdirected) do |misdirected_request|
|
||||
other_connection = connection.create_idle(ssl: { alpn_protocols: %w[http/1.1] })
|
||||
other_connection.merge(connection)
|
||||
catch(:coalesced) do
|
||||
pool.init_connection(other_connection, options)
|
||||
end
|
||||
set_connection_callbacks(other_connection, connections, options)
|
||||
connections << other_connection
|
||||
connection.unmerge(other_connection)
|
||||
misdirected_request.transition(:idle)
|
||||
other_connection.send(misdirected_request)
|
||||
end
|
||||
connection.on(:altsvc) do |alt_origin, origin, alt_params|
|
||||
other_connection = build_altsvc_connection(connection, connections, alt_origin, origin, alt_params, options)
|
||||
|
@ -85,6 +85,17 @@ class HTTPSTest < Minitest::Test
|
||||
end
|
||||
end
|
||||
|
||||
def test_http2_uncoalesce_on_misdirected
|
||||
uri = build_uri("/status/421")
|
||||
HTTPX.plugin(SessionWithPool).wrap do |http|
|
||||
response = http.get(uri)
|
||||
verify_status(response, 421)
|
||||
connection_count = http.pool.connection_count
|
||||
assert connection_count == 2, "expected to have 2 connections, instead have #{connection_count}"
|
||||
assert response.version == "1.1", "request should have been retried with HTTP/1.1"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def origin(orig = httpbin)
|
||||
|
Loading…
x
Reference in New Issue
Block a user