From 0cb2e656cd37d97f89e39d1fc6abd0bc39a3d0d2 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 21 May 2016 17:42:47 +0200 Subject: [PATCH 1/4] immediately send push to client --- mitmproxy/protocol/http2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mitmproxy/protocol/http2.py b/mitmproxy/protocol/http2.py index 1cc127921..c04bd5072 100644 --- a/mitmproxy/protocol/http2.py +++ b/mitmproxy/protocol/http2.py @@ -174,6 +174,7 @@ class Http2Layer(Layer): parent_eid = self.server_to_client_stream_ids[event.parent_stream_id] with self.client_conn.h2.lock: self.client_conn.h2.push_stream(parent_eid, event.pushed_stream_id, event.headers) + self.client_conn.send(self.client_conn.h2.data_to_send()) headers = Headers([[str(k), str(v)] for k, v in event.headers]) headers['x-mitmproxy-pushed'] = 'true' From f7ce8e219e6f64133ba9f3c56669ace350c2d521 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 21 May 2016 18:35:29 +0200 Subject: [PATCH 2/4] fix typo --- mitmproxy/protocol/http2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mitmproxy/protocol/http2.py b/mitmproxy/protocol/http2.py index c04bd5072..81bf5db91 100644 --- a/mitmproxy/protocol/http2.py +++ b/mitmproxy/protocol/http2.py @@ -169,7 +169,7 @@ class Http2Layer(Layer): # Some streams might be still sending data to the client. return False elif isinstance(event, events.PushedStreamReceived): - # pushed stream ids should be uniq and not dependent on race conditions + # pushed stream ids should be unique and not dependent on race conditions # only the parent stream id must be looked up first parent_eid = self.server_to_client_stream_ids[event.parent_stream_id] with self.client_conn.h2.lock: From 6965c93be6221f5905dcb1b290fea73c9fe652de Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 21 May 2016 20:17:59 +0200 Subject: [PATCH 3/4] implement transparent Priority updates --- mitmproxy/protocol/http2.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mitmproxy/protocol/http2.py b/mitmproxy/protocol/http2.py index 81bf5db91..3c4b59e9f 100644 --- a/mitmproxy/protocol/http2.py +++ b/mitmproxy/protocol/http2.py @@ -9,6 +9,7 @@ import six from h2.connection import H2Connection from h2.exceptions import StreamClosedError from h2 import events +from hyperframe.frame import PriorityFrame from netlib.tcp import ssl_read_select from netlib.exceptions import HttpException @@ -185,6 +186,17 @@ class Http2Layer(Layer): self.streams[event.pushed_stream_id].timestamp_end = time.time() self.streams[event.pushed_stream_id].request_data_finished.set() self.streams[event.pushed_stream_id].start() + elif isinstance(event, events.PriorityUpdated): + stream_id = event.stream_id + if stream_id in self.streams.keys() and self.streams[stream_id].server_stream_id: + stream_id = self.streams[stream_id].server_stream_id + + depends_on = event.depends_on + if depends_on in self.streams.keys() and self.streams[depends_on].server_stream_id: + depends_on = self.streams[depends_on].server_stream_id + + frame = PriorityFrame(stream_id, depends_on, event.weight, event.exclusive) + self.server_conn.send(frame.serialize()) elif isinstance(event, events.TrailersReceived): raise NotImplementedError() From 85a3a92a8adbb07663b6e4bb8ecc017de1b7b286 Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Sat, 21 May 2016 20:18:49 +0200 Subject: [PATCH 4/4] kill streams if connection gets terminated --- mitmproxy/protocol/http2.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mitmproxy/protocol/http2.py b/mitmproxy/protocol/http2.py index 3c4b59e9f..98728c8ad 100644 --- a/mitmproxy/protocol/http2.py +++ b/mitmproxy/protocol/http2.py @@ -209,6 +209,11 @@ class Http2Layer(Layer): if zombie and zombie <= death_time: self.streams.pop(stream_id, None) + def _kill_all_streams(self): + for stream in self.streams.values(): + if not stream.zombie: + stream.zombie = time.time() + def __call__(self): if self.server_conn: self._initiate_server_conn() @@ -230,9 +235,7 @@ class Http2Layer(Layer): raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile)) except: # read frame failed: connection closed - # kill all streams - for stream in self.streams.values(): - stream.zombie = time.time() + self._kill_all_streams() return incoming_events = source_conn.h2.receive_data(raw_frame) @@ -240,6 +243,8 @@ class Http2Layer(Layer): for event in incoming_events: if not self._handle_event(event, source_conn, other_conn, is_server): + # connection terminated: GoAway + self._kill_all_streams() return self._cleanup_streams()