diff options
author | Thomas Kriechbaumer <thomas@kriechbaumer.name> | 2016-05-21 20:25:02 +0200 |
---|---|---|
committer | Thomas Kriechbaumer <thomas@kriechbaumer.name> | 2016-06-04 11:20:10 +0200 |
commit | 7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a (patch) | |
tree | 53736d5fb4cb1984ae5af00a9df7f0d96d922bc4 | |
parent | e880f532ad3c66ebfded4655b7fa67a367a83cc7 (diff) | |
download | mitmproxy-7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a.tar.gz mitmproxy-7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a.tar.bz2 mitmproxy-7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a.zip |
http2: respect MAX_CONCURRENT_STREAMS by hold-off
-rw-r--r-- | mitmproxy/protocol/http2.py | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/mitmproxy/protocol/http2.py b/mitmproxy/protocol/http2.py index 39512c8f..865fe645 100644 --- a/mitmproxy/protocol/http2.py +++ b/mitmproxy/protocol/http2.py @@ -73,7 +73,7 @@ class SafeH2Connection(connection.H2Connection): frame_chunk = chunk[position:position + max_outbound_frame_size] if self.local_flow_control_window(stream_id) < len(frame_chunk): self.lock.release() - time.sleep(0) + time.sleep(0.1) continue self.send_data(stream_id, frame_chunk) self.conn.send(self.data_to_send()) @@ -352,8 +352,22 @@ class Http2SingleStreamLayer(http._HttpTransmissionLayer, threading.Thread): raise NotImplementedError() def send_request(self, message): + if not hasattr(self.server_conn, 'h2'): + raise exceptions.Http2ProtocolException("Zombie Stream") + + while True: + self.server_conn.h2.lock.acquire() + max_streams = self.server_conn.h2.remote_settings.max_concurrent_streams + if self.server_conn.h2.open_outbound_streams + 1 >= max_streams: + # wait until we get a free slot for a new outgoing stream + self.server_conn.h2.lock.release() + time.sleep(0.1) + else: + break + if self.pushed: # nothing to do here + self.server_conn.h2.lock.release() return with self.server_conn.h2.lock: @@ -364,16 +378,19 @@ class Http2SingleStreamLayer(http._HttpTransmissionLayer, threading.Thread): self.server_stream_id = self.server_conn.h2.get_next_available_stream_id() self.server_to_client_stream_ids[self.server_stream_id] = self.client_stream_id - headers = message.headers.copy() - headers.insert(0, ":path", message.path) - headers.insert(0, ":method", message.method) - headers.insert(0, ":scheme", message.scheme) + headers = message.headers.copy() + headers.insert(0, ":path", message.path) + headers.insert(0, ":method", message.method) + headers.insert(0, ":scheme", message.scheme) + self.server_stream_id = self.server_conn.h2.get_next_available_stream_id() + self.server_to_client_stream_ids[self.server_stream_id] = self.client_stream_id + self.server_conn.h2.safe_send_headers( + self.is_zombie, + self.server_stream_id, + headers, + ) + self.server_conn.h2.lock.release() - self.server_conn.h2.safe_send_headers( - self.is_zombie, - self.server_stream_id, - headers - ) self.server_conn.h2.safe_send_body( self.is_zombie, self.server_stream_id, @@ -408,7 +425,7 @@ class Http2SingleStreamLayer(http._HttpTransmissionLayer, threading.Thread): if self.response_data_finished.is_set(): while self.response_data_queue.qsize() > 0: yield self.response_data_queue.get() - return + break if self.zombie: # pragma: no cover raise exceptions.Http2ProtocolException("Zombie Stream") |