def test_simple(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('ClIeNt-FoO', 'client-bar-1'), ('ClIeNt-FoO', 'client-bar-2'), ], body='my request body echoed back to me') done = False while not done: try: events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.status_code == 200 assert self.master.state.flows[0].response.headers['server-foo'] == 'server-bar' assert self.master.state.flows[0].response.headers['föo'] == 'bär' assert self.master.state.flows[0].response.body == b'foobar'
def test_connection_terminated(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ]) done = False connection_terminated_event = None while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) for event in events: if isinstance(event, h2.events.ConnectionTerminated): connection_terminated_event = event done = True except: break assert len(self.master.state.flows) == 1 assert connection_terminated_event is not None assert connection_terminated_event.error_code == 5 assert connection_terminated_event.last_stream_id == 42 assert connection_terminated_event.additional_data == 'foobar'
def test_connection_terminated(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:{}".format( self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ]) done = False connection_terminated_event = None while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) for event in events: if isinstance(event, h2.events.ConnectionTerminated): connection_terminated_event = event done = True except: break assert len(self.master.state.flows) == 1 assert connection_terminated_event is not None assert connection_terminated_event.error_code == 5 assert connection_terminated_event.last_stream_id == 42 assert connection_terminated_event.additional_data == b'foobar'
def handle(self): h2_conn = h2.connection.H2Connection(client_side=False, header_encoding=False) preamble = self.rfile.read(24) h2_conn.initiate_connection() h2_conn.receive_data(preamble) self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() if 'h2_server_settings' in self.kwargs: h2_conn.update_settings(self.kwargs['h2_server_settings']) self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(self.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False except: break self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() for event in events: try: if not self.server.handle_server_event(event, h2_conn, self.rfile, self.wfile): done = True break except: done = True break
def test_connection_lost(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar') ]) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False except: break try: client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() except: break if len(self.master.state.flows) == 1: assert self.master.state.flows[0].response is None
def handle(self): h2_conn = h2.connection.H2Connection(client_side=False, header_encoding=False) preamble = self.rfile.read(24) h2_conn.initiate_connection() h2_conn.receive_data(preamble) self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame( self.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False except: break self.wfile.write(h2_conn.data_to_send()) self.wfile.flush() for event in events: try: if not self.server.handle_server_event( event, h2_conn, self.rfile, self.wfile): done = True break except: done = True break
def test_connection_lost(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[(':authority', "127.0.0.1:{}".format( self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar')]) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False except: break try: client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() except: break if len(self.master.state.flows) == 1: assert self.master.state.flows[0].response is None
def test_with_bodies(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], body='foobar with request body', ) done = False while not done: try: events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert self.master.state.flows[0].response.body == b'foobar with request body'
def test_push_promise_reset(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[(':authority', "127.0.0.1:{}".format( self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar')]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded) and event.stream_id == 1: ended_streams += 1 elif isinstance(event, h2.events.PushedStreamReceived): pushed_streams += 1 h2_conn.reset_stream(event.pushed_stream_id, error_code=0x8) client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() elif isinstance(event, h2.events.ResponseReceived): responses += 1 if isinstance(event, h2.events.ConnectionTerminated): done = True if responses >= 1 and ended_streams >= 1 and pushed_streams == 2: done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() bodies = [ flow.response.body for flow in self.master.state.flows if flow.response ] assert len(bodies) >= 1 assert b'regular_stream' in bodies
def handle(self): # send magic self.wfile.write(codecs.decode('505249202a20485454502f322e300d0a0d0a534d0d0a0d0a', 'hex_codec')) self.wfile.flush() # send empty settings frame self.wfile.write(codecs.decode('000000040000000000', 'hex_codec')) self.wfile.flush() # check empty settings frame raw = framereader.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('00000c040000000000000200000000000300000001', 'hex_codec') # check settings acknowledgement raw = framereader.http2_read_raw_frame(self.rfile) assert raw == codecs.decode('000000040100000000', 'hex_codec') # send settings acknowledgement self.wfile.write(codecs.decode('000000040100000000', 'hex_codec')) self.wfile.flush()
def handle(self): # send magic self.wfile.write(codecs.decode("505249202a20485454502f322e300d0a0d0a534d0d0a0d0a", "hex_codec")) self.wfile.flush() # send empty settings frame self.wfile.write(codecs.decode("000000040000000000", "hex_codec")) self.wfile.flush() # check empty settings frame raw = framereader.http2_read_raw_frame(self.rfile) assert raw == codecs.decode("00000c040000000000000200000000000300000001", "hex_codec") # check settings acknowledgement raw = framereader.http2_read_raw_frame(self.rfile) assert raw == codecs.decode("000000040100000000", "hex_codec") # send settings acknowledgement self.wfile.write(codecs.decode("000000040100000000", "hex_codec")) self.wfile.flush()
def test_push_promise(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar') ]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): ended_streams += 1 elif isinstance(event, h2.events.PushedStreamReceived): pushed_streams += 1 elif isinstance(event, h2.events.ResponseReceived): responses += 1 if isinstance(event, h2.events.ConnectionTerminated): done = True if responses == 3 and ended_streams == 3 and pushed_streams == 2: done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert ended_streams == 3 assert pushed_streams == 2 bodies = [flow.response.body for flow in self.master.state.flows] assert len(bodies) == 3 assert b'regular_stream' in bodies assert b'pushed_stream_foo' in bodies assert b'pushed_stream_bar' in bodies
def test_push_promise(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[(':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar')]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): ended_streams += 1 elif isinstance(event, h2.events.PushedStreamReceived): pushed_streams += 1 elif isinstance(event, h2.events.ResponseReceived): responses += 1 if isinstance(event, h2.events.ConnectionTerminated): done = True if responses == 3 and ended_streams == 3 and pushed_streams == 2: done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert ended_streams == 3 assert pushed_streams == 2 bodies = [flow.response.body for flow in self.master.state.flows] assert len(bodies) == 3 assert b'regular_stream' in bodies assert b'pushed_stream_foo' in bodies assert b'pushed_stream_bar' in bodies
def test_simple(self): response_body_buffer = b'' client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:{}".format( self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('ClIeNt-FoO', 'client-bar-1'), ('ClIeNt-FoO', 'client-bar-2'), ], body=b'request body') done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.DataReceived): response_body_buffer += event.data elif isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.status_code == 200 assert self.master.state.flows[0].response.headers[ 'server-foo'] == 'server-bar' assert self.master.state.flows[0].response.headers['föo'] == 'bär' assert self.master.state.flows[0].response.body == b'response body' assert self.request_body_buffer == b'request body' assert response_body_buffer == b'response body'
def test_push_promise_reset(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, stream_id=1, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('foo', 'bar') ]) done = False ended_streams = 0 pushed_streams = 0 responses = 0 while not done: try: events = h2_conn.receive_data(b''.join(framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded) and event.stream_id == 1: ended_streams += 1 elif isinstance(event, h2.events.PushedStreamReceived): pushed_streams += 1 h2_conn.reset_stream(event.pushed_stream_id, error_code=0x8) client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() elif isinstance(event, h2.events.ResponseReceived): responses += 1 if isinstance(event, h2.events.ConnectionTerminated): done = True if responses >= 1 and ended_streams >= 1 and pushed_streams == 2: done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() bodies = [flow.response.body for flow in self.master.state.flows if flow.response] assert len(bodies) >= 1 assert b'regular_stream' in bodies
def test_simple(self): response_body_buffer = b'' client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('ClIeNt-FoO', 'client-bar-1'), ('ClIeNt-FoO', 'client-bar-2'), ], body=b'request body') done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.DataReceived): response_body_buffer += event.data elif isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.status_code == 200 assert self.master.state.flows[0].response.headers['server-foo'] == 'server-bar' assert self.master.state.flows[0].response.headers['föo'] == 'bär' assert self.master.state.flows[0].response.body == b'response body' assert self.request_body_buffer == b'request body' assert response_body_buffer == b'response body'
def test_request_with_priority(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], priority_exclusive=True, priority_depends_on=42424242, priority_weight=42, ) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.headers[ 'priority_exclusive'] == 'True' assert self.master.state.flows[0].response.headers[ 'priority_depends_on'] == '42424242' assert self.master.state.flows[0].response.headers[ 'priority_weight'] == '42'
def test_priority_with_existing_stream(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], end_stream=False, ) h2_conn.prioritize(1, exclusive=True, depends_on=0, weight=42) h2_conn.end_stream(1) client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.priority_data == [(True, 0, 42)]
def test_request_with_priority(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], priority_exclusive = True, priority_depends_on = 42424242, priority_weight = 42, ) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.headers['priority_exclusive'] == 'True' assert self.master.state.flows[0].response.headers['priority_depends_on'] == '42424242' assert self.master.state.flows[0].response.headers['priority_weight'] == '42'
def test_simple(self): client, h2_conn = self._setup_connection() self._send_request(client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('ClIeNt-FoO', 'client-bar-1'), ('ClIeNt-FoO', 'client-bar-2'), ], body='my request body echoed back to me') done = False while not done: try: events = h2_conn.receive_data(b''.join( framereader.http2_read_raw_frame(client.rfile))) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 1 assert self.master.state.flows[0].response.status_code == 200 assert self.master.state.flows[0].response.headers[ 'server-foo'] == 'server-bar' assert self.master.state.flows[0].response.headers['föo'] == 'bär' assert self.master.state.flows[0].response.body == b'foobar'
def test_max_concurrent_streams(self): client, h2_conn = self._setup_connection() new_streams = [1, 3, 5, 7, 9, 11] for id in new_streams: # this will exceed MAX_CONCURRENT_STREAMS on the server connection # and cause mitmproxy to throttle stream creation to the server self._send_request(client.wfile, h2_conn, stream_id=id, headers=[ (':authority', "127.0.0.1:{}".format( self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('X-Stream-ID', str(id)), ]) ended_streams = 0 while ended_streams != len(new_streams): try: header, body = framereader.http2_read_raw_frame(client.rfile) events = h2_conn.receive_data(b''.join([header, body])) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): ended_streams += 1 h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == len(new_streams) for flow in self.master.state.flows: assert flow.response.status_code == 200 assert b"Stream-ID " in flow.response.body
def test_body_size_limit(self): self.config.options.body_size_limit = 20 client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], body=b'very long body over 20 characters long', ) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamReset): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 0
def test_body_size_limit(self): self.config.body_size_limit = 20 client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], body=b'very long body over 20 characters long', ) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamReset): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == 0
def test_with_bodies(self): client, h2_conn = self._setup_connection() self._send_request( client.wfile, h2_conn, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ], body='foobar with request body', ) done = False while not done: try: raw = b''.join(framereader.http2_read_raw_frame(client.rfile)) events = h2_conn.receive_data(raw) except HttpException: print(traceback.format_exc()) assert False client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): done = True h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert self.master.state.flows[ 0].response.body == b'foobar with request body'
def test_max_concurrent_streams(self): client, h2_conn = self._setup_connection() new_streams = [1, 3, 5, 7, 9, 11] for id in new_streams: # this will exceed MAX_CONCURRENT_STREAMS on the server connection # and cause mitmproxy to throttle stream creation to the server self._send_request(client.wfile, h2_conn, stream_id=id, headers=[ (':authority', "127.0.0.1:%s" % self.server.server.address.port), (':method', 'GET'), (':scheme', 'https'), (':path', '/'), ('X-Stream-ID', str(id)), ]) ended_streams = 0 while ended_streams != len(new_streams): try: header, body = framereader.http2_read_raw_frame(client.rfile) events = h2_conn.receive_data(b''.join([header, body])) except: break client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() for event in events: if isinstance(event, h2.events.StreamEnded): ended_streams += 1 h2_conn.close_connection() client.wfile.write(h2_conn.data_to_send()) client.wfile.flush() assert len(self.master.state.flows) == len(new_streams) for flow in self.master.state.flows: assert flow.response.status_code == 200 assert "Stream-ID" in flow.response.body