def test_on_response(self): client_conn = Connection( self.client_stream, client_side=True, on_response=self.on_response, on_unhandled=mock.Mock()) client_conn.initiate_connection() client_conn.send_request( client_conn.get_next_available_stream_id(), HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) server_conn = Connection( self.server_stream, client_side=False, on_request=self.on_request, on_unhandled=mock.Mock()) server_conn.initiate_connection() yield server_conn.read_bytes() server_conn.send_response( self.request[0], HttpResponse( headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) yield client_conn.read_bytes() self.assertIsNotNone(self.response) _, response = self.response self.assertEqual(response.headers, HttpHeaders([ (":status", "200"), ("aaa", "bbb")])) self.assertEqual(response.code, "200") self.assertEqual(response.version, "HTTP/2")
def test_on_request(self): client_conn = Connection(self.client_stream, client_side=True) client_conn.initiate_connection() client_conn.send_request( client_conn.get_next_available_stream_id(), HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) server_conn = Connection( self.server_stream, client_side=False, on_request=self.on_request, on_settings=self.on_settings) server_conn.initiate_connection() yield server_conn.read_bytes() self.assertIsNotNone(self.request) _, request = self.request self.assertEqual(request.headers, HttpHeaders([ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2")
def test_on_pushed_stream(self): client_conn = Connection( self.client_stream, client_side=True, on_push=self.on_push, on_unhandled=mock.Mock()) client_conn.initiate_connection() client_conn.send_request( client_conn.get_next_available_stream_id(), HttpRequest(headers=[ (":method", "GET"), (":path", "/")])) server_conn = Connection( self.server_stream, client_side=False, on_request=self.on_request, on_unhandled=mock.Mock()) server_conn.initiate_connection() yield server_conn.read_bytes() stream_id, _ = self.request server_conn.send_pushed_stream( stream_id, 2, HttpRequest(headers=[ (":method", "GET"), (":path", "/resource")])) yield client_conn.read_bytes() self.assertIsNotNone(self.push) self.assertEqual(self.push["parent_stream_id"], 1) self.assertEqual(self.push["pushed_stream_id"], 2) self.assertEqual( self.push["request"].headers, HttpHeaders([ (":method", "GET"), (":path", "/resource")]))
def test_readonly(self): client_conn = Connection(self.client_stream, client_side=True, readonly=True) client_conn.initiate_connection() client_conn.send_request( client_conn.get_next_available_stream_id(), HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) with self.assertRaises(gen.TimeoutError): yield gen.with_timeout( timedelta(milliseconds=100), self.server_stream.read_bytes(1))
def test_on_reset(self): client_conn = Connection( self.client_stream, client_side=True, on_reset=self.on_reset, on_unhandled=mock.Mock()) client_conn.initiate_connection() client_conn.send_request( client_conn.get_next_available_stream_id(), HttpRequest(headers=[ (":method", "GET"), (":path", "/")])) server_conn = Connection( self.server_stream, client_side=False, on_request=self.on_request, on_unhandled=mock.Mock()) yield server_conn.read_bytes() stream_id, _ = self.request server_conn.send_reset(stream_id, 2) yield client_conn.read_bytes() self.assertIsNotNone(self.reset) self.assertEqual(self.reset, (stream_id, 2))
def test_on_priority_updates(self): client_conn = Connection( self.client_stream, client_side=True, on_unhandled=mock.Mock()) client_conn.initiate_connection() stream_id = client_conn.get_next_available_stream_id() client_conn.send_request( stream_id, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) client_conn.send_priority_updates( stream_id, 0, 10, False) server_conn = Connection( self.server_stream, client_side=False, on_priority_updates=self.on_priority_updates, on_unhandled=mock.Mock()) server_conn.initiate_connection() yield server_conn.read_bytes() self.assertIsNotNone(self.priority_updates) self.assertEqual( self.priority_updates, dict(stream_id=stream_id, depends_on=0, weight=10, exclusive=False))
class TestHttp2Layer(ProxyAsyncTestCase): def setUp(self): super(TestHttp2Layer, self).setUp() self.asyncSetUp() self.src_events = [] self.dest_events = [] @gen_test def asyncSetUp(self): self.client_stream, src_stream = yield self.create_iostream_pair() dest_stream, self.server_stream = yield self.create_iostream_pair() server_state = ServerContext(config={}, interceptor=mock.Mock( **{ "publish.return_value": None, "request.return_value": None, "response.return_value": None, })) self.http_layer = Http2Layer( server_state, LayerContext(mode="socks", src_stream=src_stream, dest_stream=dest_stream)) def record_src_event(self, *args): self.src_events.append(args) def record_dest_event(self, *args): self.dest_events.append(args) def ignore_event(self, *args): pass @coroutine def read_until_new_event(self, conn, events): curr_count = len(events) while curr_count == len(events): yield conn.read_bytes() @gen_test def test_req_and_resp(self): self.client_conn = Connection(self.client_stream, client_side=True, on_response=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_response( 1, HttpResponse(headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() result = yield result_future self.assertIsNotNone(result) self.assertIsInstance(result, LayerContext) self.assertEqual(len(self.src_events), 1) stream_id, response = self.src_events[0] self.assertEqual(stream_id, 1) self.assertEqual(response.code, "200") self.assertEqual(response.version, "HTTP/2") self.assertEqual(response.headers, HttpHeaders([(":status", "200"), ("aaa", "bbb")])) self.assertEqual(response.body, b"ccc") self.assertEqual(len(self.dest_events), 1) stream_id, request, _ = self.dest_events[0] self.assertEqual(stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) @gen_test def test_req_with_priority_updated(self): self.client_conn = Connection(self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")]), priority_weight=10, priority_depends_on=0, priority_exclusive=False) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.dest_events), 1) stream_id, request, priority_updated = self.dest_events[0] self.assertEqual(stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.assertIsNotNone(priority_updated) self.assertEqual(priority_updated.weight, 10) self.assertEqual(priority_updated.exclusive, False) self.assertEqual(priority_updated.depends_on, 0) @gen_test def test_push(self): self.client_conn = Connection(self.client_stream, client_side=True, on_response=self.record_src_event, on_push=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_pushed_stream( 1, 2, HttpRequest(headers=[(":method", "GET"), (":path", "/resource")])) yield self.read_until_new_event(self.client_conn, self.src_events) self.server_conn.send_response( 2, HttpResponse(headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.src_events), 2) stream_id, parent_stream_id, request = self.src_events[0] self.assertEqual(stream_id, 2) self.assertEqual(parent_stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/resource") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/resource")])) stream_id, response = self.src_events[1] self.assertEqual(stream_id, 2) self.assertEqual(response.code, "200") self.assertEqual(response.version, "HTTP/2") self.assertEqual(response.headers, HttpHeaders([(":status", "200"), ("aaa", "bbb")])) @gen_test def test_window_updates(self): self.client_conn = Connection(self.client_stream, client_side=True, on_window_updates=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_window_updates=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_window_updates(0, 100) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.client_conn.send_window_updates(1, 200) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_window_updates(1, 300) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future print self.src_events self.assertEqual(len(self.src_events), 1) self.assertEqual(self.src_events[0], (1, 300)) self.assertEqual(len(self.dest_events), 2) self.assertEqual(self.dest_events[0], (0, 100)) self.assertEqual(self.dest_events[1], (1, 200)) @gen_test def test_priority_updated(self): self.client_conn = Connection(self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_priority_updates=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.client_conn.send_priority_updates(1, 0, 10, False) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.dest_events), 1) self.assertEqual(self.dest_events[0], (1, 0, 10, False)) @gen_test def test_reset(self): self.client_conn = Connection(self.client_stream, client_side=True, on_reset=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_request=self.record_dest_event, on_reset=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_conn.send_reset(1, 0) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_conn.send_request( 3, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_reset(3, 0) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.src_events), 1) self.assertEqual(self.src_events[0], (3, 0)) self.assertEqual(len(self.dest_events), 3) # NOTE: req, reset, req self.assertEqual(self.dest_events[1], (1, 0)) @gen_test def test_src_send_terminate(self): self.client_conn = Connection(self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_terminate=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_terminate() yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.dest_events), 1) self.assertEqual(self.dest_events[0], (None, 0, 0)) @gen_test def test_dest_send_terminate(self): self.client_conn = Connection(self.client_stream, client_side=True, on_terminate=self.record_src_event, on_settings=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() # NOTE: because hyper-h2 will always send SettingsChanged when init # Than client will receive two setting frame from destination and server yield self.read_until_new_event(self.client_conn, self.src_events) yield self.read_until_new_event(self.client_conn, self.src_events) self.server_conn.send_terminate() yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.src_events), 3) self.assertEqual(self.src_events[2], (None, 0, 0)) @gen_test def test_safe_mapping_id(self): self.client_conn = Connection(self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.assertEqual( self.http_layer.safe_mapping_id(self.http_layer.src_to_dest_ids, 1), 0) self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.assertEqual( self.http_layer.safe_mapping_id(self.http_layer.src_to_dest_ids, 1), 1) self.client_stream.close() self.server_stream.close() yield result_future @gen_test def test_replay(self): self.http_layer.context.mode = "replay" self.client_conn = Connection(self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection(self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_response( 1, HttpResponse(headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) result = yield result_future self.assertIsNotNone(result) self.assertIsInstance(result, LayerContext) self.assertEqual(len(self.dest_events), 1) stream_id, request, _ = self.dest_events[0] self.assertEqual(stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) def tearDown(self): self.client_stream.close() self.server_stream.close() self.http_layer.src_stream.close() self.http_layer.dest_stream.close()
class TestHttp2Layer(ProxyAsyncTestCase): def setUp(self): super(TestHttp2Layer, self).setUp() self.asyncSetUp() self.src_events = [] self.dest_events = [] @gen_test def asyncSetUp(self): self.client_stream, src_stream = yield self.create_iostream_pair() dest_stream, self.server_stream = yield self.create_iostream_pair() server_state = ServerContext( config={}, interceptor=mock.Mock(**{ "publish.return_value": None, "request.return_value": None, "response.return_value": None, }) ) self.http_layer = Http2Layer( server_state, LayerContext(mode="socks", src_stream=src_stream, dest_stream=dest_stream)) def record_src_event(self, *args): self.src_events.append(args) def record_dest_event(self, *args): self.dest_events.append(args) def ignore_event(self, *args): pass @coroutine def read_until_new_event(self, conn, events): curr_count = len(events) while curr_count == len(events): yield conn.read_bytes() @gen_test def test_req_and_resp(self): self.client_conn = Connection( self.client_stream, client_side=True, on_response=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_response( 1, HttpResponse(headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() result = yield result_future self.assertIsNotNone(result) self.assertIsInstance(result, LayerContext) self.assertEqual(len(self.src_events), 1) stream_id, response = self.src_events[0] self.assertEqual(stream_id, 1) self.assertEqual(response.code, "200") self.assertEqual(response.version, "HTTP/2") self.assertEqual( response.headers, HttpHeaders([(":status", "200"), ("aaa", "bbb")])) self.assertEqual(response.body, b"ccc") self.assertEqual(len(self.dest_events), 1) stream_id, request, _ = self.dest_events[0] self.assertEqual(stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) @gen_test def test_req_with_priority_updated(self): self.client_conn = Connection( self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")]), priority_weight=10, priority_depends_on=0, priority_exclusive=False) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.dest_events), 1) stream_id, request, priority_updated = self.dest_events[0] self.assertEqual(stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.assertIsNotNone(priority_updated) self.assertEqual(priority_updated.weight, 10) self.assertEqual(priority_updated.exclusive, False) self.assertEqual(priority_updated.depends_on, 0) @gen_test def test_push(self): self.client_conn = Connection( self.client_stream, client_side=True, on_response=self.record_src_event, on_push=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_pushed_stream(1, 2, HttpRequest( headers=[(":method", "GET"), (":path", "/resource")])) yield self.read_until_new_event(self.client_conn, self.src_events) self.server_conn.send_response( 2, HttpResponse(headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.src_events), 2) stream_id, parent_stream_id, request = self.src_events[0] self.assertEqual(stream_id, 2) self.assertEqual(parent_stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/resource") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/resource")])) stream_id, response = self.src_events[1] self.assertEqual(stream_id, 2) self.assertEqual(response.code, "200") self.assertEqual(response.version, "HTTP/2") self.assertEqual( response.headers, HttpHeaders([(":status", "200"), ("aaa", "bbb")])) @gen_test def test_window_updates(self): self.client_conn = Connection( self.client_stream, client_side=True, on_window_updates=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_window_updates=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_window_updates(0, 100) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.client_conn.send_window_updates(1, 200) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_window_updates(1, 300) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future print self.src_events self.assertEqual(len(self.src_events), 1) self.assertEqual(self.src_events[0], (1, 300)) self.assertEqual(len(self.dest_events), 2) self.assertEqual(self.dest_events[0], (0, 100)) self.assertEqual(self.dest_events[1], (1, 200)) @gen_test def test_priority_updated(self): self.client_conn = Connection( self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_priority_updates=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) self.client_conn.send_priority_updates(1, 0, 10, False) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.dest_events), 1) self.assertEqual(self.dest_events[0], (1, 0, 10, False)) @gen_test def test_reset(self): self.client_conn = Connection( self.client_stream, client_side=True, on_reset=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_request=self.record_dest_event, on_reset=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_conn.send_reset(1, 0) yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_conn.send_request( 3, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_reset(3, 0) yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.src_events), 1) self.assertEqual(self.src_events[0], (3, 0)) self.assertEqual(len(self.dest_events), 3) # NOTE: req, reset, req self.assertEqual(self.dest_events[1], (1, 0)) @gen_test def test_src_send_terminate(self): self.client_conn = Connection( self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_terminate=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_terminate() yield self.read_until_new_event(self.server_conn, self.dest_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.dest_events), 1) self.assertEqual(self.dest_events[0], (None, 0, 0)) @gen_test def test_dest_send_terminate(self): self.client_conn = Connection( self.client_stream, client_side=True, on_terminate=self.record_src_event, on_settings=self.record_src_event, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() # NOTE: because hyper-h2 will always send SettingsChanged when init # Than client will receive two setting frame from destination and server yield self.read_until_new_event(self.client_conn, self.src_events) yield self.read_until_new_event(self.client_conn, self.src_events) self.server_conn.send_terminate() yield self.read_until_new_event(self.client_conn, self.src_events) self.client_stream.close() self.server_stream.close() yield result_future self.assertEqual(len(self.src_events), 3) self.assertEqual(self.src_events[2], (None, 0, 0)) @gen_test def test_safe_mapping_id(self): self.client_conn = Connection( self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.assertEqual( self.http_layer.safe_mapping_id(self.http_layer.src_to_dest_ids, 1), 0) self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.assertEqual( self.http_layer.safe_mapping_id(self.http_layer.src_to_dest_ids, 1), 1) self.client_stream.close() self.server_stream.close() yield result_future @gen_test def test_replay(self): self.http_layer.context.mode = "replay" self.client_conn = Connection( self.client_stream, client_side=True, on_unhandled=self.ignore_event) self.server_conn = Connection( self.server_stream, client_side=False, on_request=self.record_dest_event, on_unhandled=self.ignore_event) result_future = self.http_layer.process_and_return_context() self.client_conn.initiate_connection() self.server_conn.initiate_connection() self.client_conn.send_request( 1, HttpRequest(headers=[ (":method", "GET"), (":path", "/"), ("aaa", "bbb")])) yield self.read_until_new_event(self.server_conn, self.dest_events) self.server_conn.send_response( 1, HttpResponse(headers=[(":status", "200"), ("aaa", "bbb")], body=b"ccc")) result = yield result_future self.assertIsNotNone(result) self.assertIsInstance(result, LayerContext) self.assertEqual(len(self.dest_events), 1) stream_id, request, _ = self.dest_events[0] self.assertEqual(stream_id, 1) self.assertEqual(request.method, "GET") self.assertEqual(request.path, "/") self.assertEqual(request.version, "HTTP/2") self.assertEqual( request.headers, HttpHeaders([(":method", "GET"), (":path", "/"), ("aaa", "bbb")])) def tearDown(self): self.client_stream.close() self.server_stream.close() self.http_layer.src_stream.close() self.http_layer.dest_stream.close()