From cfaba15c1f2dbf39891a7e3bacf59f8eafca1332 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 19 Feb 2021 19:34:52 +0100 Subject: [PATCH] fix regression introduced in 70e08c880 (#4459) --- mitmproxy/proxy/layers/http/__init__.py | 8 ++++--- .../mitmproxy/proxy/layers/http/test_http2.py | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/mitmproxy/proxy/layers/http/__init__.py b/mitmproxy/proxy/layers/http/__init__.py index 76b38e3e9..1705b8934 100644 --- a/mitmproxy/proxy/layers/http/__init__.py +++ b/mitmproxy/proxy/layers/http/__init__.py @@ -628,16 +628,18 @@ class HttpLayer(layer.Layer): h2_to_h1 = self.context.client.alpn == b"h2" and not conn_is_pending_or_h2 connection_suitable = ( event.connection_spec_matches(connection) - and connection.connected and not h2_to_h1 ) if connection_suitable: if connection in self.waiting_for_establishment: self.waiting_for_establishment[connection].append(event) - else: + return + elif connection.connected: stream = self.command_sources.pop(event) yield from self.event_to_child(stream, GetHttpConnectionCompleted(event, (connection, None))) - return + return + else: + pass # the connection is at least half-closed already, we want a new one. can_use_context_connection = ( self.context.server not in self.connections and diff --git a/test/mitmproxy/proxy/layers/http/test_http2.py b/test/mitmproxy/proxy/layers/http/test_http2.py index 52dedce98..6fe97bb9e 100644 --- a/test/mitmproxy/proxy/layers/http/test_http2.py +++ b/test/mitmproxy/proxy/layers/http/test_http2.py @@ -467,6 +467,29 @@ def test_max_concurrency(tctx): assert req2.stream_id == 3 +def test_stream_concurrent_get_connection(tctx): + """Test that an immediate second request for the same domain does not trigger a second connection attempt.""" + playbook, cff = start_h2_client(tctx) + playbook.hooks = False + + server = Placeholder(Server) + data = Placeholder(bytes) + + assert (playbook + >> DataReceived(tctx.client, cff.build_headers_frame(example_request_headers, flags=["END_STREAM"], stream_id=1).serialize()) + << (o := OpenConnection(server)) + >> DataReceived(tctx.client, cff.build_headers_frame(example_request_headers, flags=["END_STREAM"], stream_id=3).serialize()) + >> reply(None, to=o, side_effect=make_h2) + << SendData(server, data) + ) + frames = decode_frames(data()) + assert [type(x) for x in frames] == [ + hyperframe.frame.SettingsFrame, + hyperframe.frame.HeadersFrame, + hyperframe.frame.HeadersFrame, + ] + + def test_kill_stream(tctx): """Test that we can kill individual streams.""" playbook, cff = start_h2_client(tctx)