aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Kriechbaumer <thomas@kriechbaumer.name>2016-05-21 20:25:02 +0200
committerThomas Kriechbaumer <thomas@kriechbaumer.name>2016-06-04 11:20:10 +0200
commit7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a (patch)
tree53736d5fb4cb1984ae5af00a9df7f0d96d922bc4
parente880f532ad3c66ebfded4655b7fa67a367a83cc7 (diff)
downloadmitmproxy-7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a.tar.gz
mitmproxy-7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a.tar.bz2
mitmproxy-7f4ac6f27bf7ed9b4fbd5bde616d9b2d2f81145a.zip
http2: respect MAX_CONCURRENT_STREAMS by hold-off
-rw-r--r--mitmproxy/protocol/http2.py39
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")