From ae6fe83adbbfee4ecbbca498f3f638a57219ce1d Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 8 Feb 2020 16:55:49 +0000 Subject: [PATCH] fix #3780 --- mitmproxy/proxy/protocol/http2.py | 33 +++++++++++++++++++++++-------- setup.py | 2 +- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/mitmproxy/proxy/protocol/http2.py b/mitmproxy/proxy/protocol/http2.py index a5870e6c8..89e652e3d 100644 --- a/mitmproxy/proxy/protocol/http2.py +++ b/mitmproxy/proxy/protocol/http2.py @@ -87,6 +87,18 @@ class Http2Layer(base.Layer): # mypy type hints client_conn: connections.ClientConnection = None + class H2ConnLogger: + def __init__(self, name, log): + self.name = name + self.log = log + + def debug(self, fmtstr, *args): + msg = "H2Conn {}: {}".format(self.name, fmtstr % args) + self.log(msg, "debug") + + def trace(self, fmtstr, *args): + pass + def __init__(self, ctx, mode: str) -> None: super().__init__(ctx) self.mode = mode @@ -98,7 +110,8 @@ class Http2Layer(base.Layer): client_side=False, header_encoding=False, validate_outbound_headers=False, - validate_inbound_headers=False) + validate_inbound_headers=False, + logger=self.H2ConnLogger("client", self.log)) self.connections[self.client_conn] = SafeH2Connection(self.client_conn, config=config) def _initiate_server_conn(self): @@ -107,7 +120,8 @@ class Http2Layer(base.Layer): client_side=True, header_encoding=False, validate_outbound_headers=False, - validate_inbound_headers=False) + validate_inbound_headers=False, + logger=self.H2ConnLogger("server", self.log)) self.connections[self.server_conn] = SafeH2Connection(self.server_conn, config=config) self.connections[self.server_conn].initiate_connection() self.server_conn.send(self.connections[self.server_conn].data_to_send()) @@ -195,10 +209,12 @@ class Http2Layer(base.Layer): else: self.streams[eid].data_queue.put(event.data) self.streams[eid].queued_data_length += len(event.data) - self.connections[source_conn].safe_acknowledge_received_data( - event.flow_controlled_length, - event.stream_id - ) + + # always acknowledge receved data with a WINDOW_UPDATE frame + self.connections[source_conn].safe_acknowledge_received_data( + event.flow_controlled_length, + event.stream_id + ) return True def _handle_stream_ended(self, eid): @@ -461,7 +477,7 @@ class Http2SingleStreamLayer(httpbase._HttpTransmissionLayer, basethread.BaseThr if self.zombie is not None or connection_closed: if pre_command is not None: pre_command() - raise exceptions.Http2ZombieException("Connection already dead") + raise exceptions.Http2ZombieException("Connection or stream already dead: {}, {}".format(self.zombie, connection_closed)) @detect_zombie_stream def read_request_headers(self, flow): @@ -643,7 +659,8 @@ class Http2SingleStreamLayer(httpbase._HttpTransmissionLayer, basethread.BaseThr try: layer() except exceptions.Http2ZombieException: # pragma: no cover - pass + # zombies can be safely terminated - no need to kill them twice + return except exceptions.ProtocolException as e: # pragma: no cover self.log(repr(e), "info") except exceptions.SetServerNotAllowedException as e: # pragma: no cover diff --git a/setup.py b/setup.py index 690a433a1..c5edee18c 100644 --- a/setup.py +++ b/setup.py @@ -68,7 +68,7 @@ setup( "click>=7.0,<8", "cryptography>=2.1.4,<2.5", "flask>=1.1.1,<1.2", - "h2>=3.0.1,<4", + "h2>=3.2.0,<4", "hyperframe>=5.1.0,<6", "kaitaistruct>=0.7,<0.9", "ldap3>=2.6.1,<2.7",