def test_handle_stop_sending_frame_receive_only(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # server creates unidirectional stream 3 server.create_stream(is_unidirectional=True) # client receives STOP_SENDING with self.assertRaises(QuicConnectionError) as cm: client._handle_stop_sending_frame( tls.Epoch.ONE_RTT, QuicFrameType.STOP_SENDING, Buffer(data=b"\x03\x11\x22"), ) self.assertEqual(cm.exception.error_code, QuicErrorCode.STREAM_STATE_ERROR) self.assertEqual(cm.exception.frame_type, QuicFrameType.STOP_SENDING) self.assertEqual(cm.exception.reason_phrase, "Stream is receive-only")
def test_handle_stream_data_blocked_frame_send_only(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # client creates unidirectional stream 2 client.create_stream(is_unidirectional=True) # client receives STREAM_DATA_BLOCKED with self.assertRaises(QuicConnectionError) as cm: client._handle_stream_data_blocked_frame( tls.Epoch.ONE_RTT, QuicFrameType.STREAM_DATA_BLOCKED, Buffer(data=b"\x02\x01"), ) self.assertEqual(cm.exception.error_code, QuicErrorCode.STREAM_STATE_ERROR) self.assertEqual(cm.exception.frame_type, QuicFrameType.STREAM_DATA_BLOCKED) self.assertEqual(cm.exception.reason_phrase, "Stream is send-only")
def test_handle_max_stream_data_frame(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # client creates bidirectional stream 0 stream = client.create_stream()[1].transport self.assertEqual(stream.max_stream_data_remote, 1048576) # client receives MAX_STREAM_DATA raising limit client._handle_max_stream_data_frame( tls.Epoch.ONE_RTT, QuicFrameType.MAX_STREAM_DATA, Buffer(data=b"\x00" + encode_uint_var(1048577)), ) self.assertEqual(stream.max_stream_data_remote, 1048577) # client receives MAX_STREAM_DATA lowering limit client._handle_max_stream_data_frame( tls.Epoch.ONE_RTT, QuicFrameType.MAX_STREAM_DATA, Buffer(data=b"\x00" + encode_uint_var(1048575)), ) self.assertEqual(stream.max_stream_data_remote, 1048577)
def test_connection_lost_with_exception(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) self.assertEqual(client_transport.sent, 4) self.assertEqual(server_transport.sent, 4) run(client.connect()) # send data over stream client_reader, client_writer = client.create_stream() client_writer.write(b"ping") run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 5) self.assertEqual(server_transport.sent, 5) # break connection exc = Exception("some error") client.connection_lost(exc) with self.assertRaises(Exception) as cm: run(client_reader.read()) self.assertEqual(cm.exception, exc)
def test_handle_stop_sending_frame(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # client creates bidirectional stream 0 client.create_stream() # client receives STOP_SENDING client._handle_stop_sending_frame(tls.Epoch.ONE_RTT, QuicFrameType.STOP_SENDING, Buffer(data=b"\x00\x11\x22"))
def test_handle_stream_data_blocked_frame(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # client creates bidirectional stream 0 client.create_stream() # client receives STREAM_DATA_BLOCKED client._handle_stream_data_blocked_frame( tls.Epoch.ONE_RTT, QuicFrameType.STREAM_DATA_BLOCKED, Buffer(data=b"\x00\x01"), )
def test_handle_reset_stream_frame(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # client creates bidirectional stream 0 client.create_stream() # client receives RESET_STREAM client._handle_reset_stream_frame( tls.Epoch.ONE_RTT, QuicFrameType.RESET_STREAM, Buffer(data=binascii.unhexlify("001122000001")), )
def _test_connect_with_version(self, client_versions, server_versions): client = QuicConnection(is_client=True) client.supported_versions = client_versions server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) server.supported_versions = server_versions # perform handshake client_transport, server_transport = create_transport(client, server) self.assertEqual(client_transport.sent, 4) self.assertEqual(server_transport.sent, 3) # check each endpoint has available connection IDs for the peer self.assertEqual( sequence_numbers(client._peer_cid_available), [1, 2, 3, 4, 5, 6, 7] ) self.assertEqual( sequence_numbers(server._peer_cid_available), [1, 2, 3, 4, 5, 6, 7] ) # send data over stream client_reader, client_writer = run(client.create_stream()) client_writer.write(b"ping") run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 5) self.assertEqual(server_transport.sent, 4) # FIXME: needs an API server_reader, server_writer = ( server.streams[0].reader, server.streams[0].writer, ) self.assertEqual(run(server_reader.read(1024)), b"ping") server_writer.write(b"pong") run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 6) self.assertEqual(server_transport.sent, 5) # client receives pong self.assertEqual(run(client_reader.read(1024)), b"pong") # client writes EOF client_writer.write_eof() run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 7) self.assertEqual(server_transport.sent, 6) # server receives EOF self.assertEqual(run(server_reader.read()), b"")
def _test_connect_with_version(self, client_versions, server_versions): client = QuicConnection(is_client=True) client.supported_versions = client_versions server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) server.supported_versions = server_versions # perform handshake client_transport, server_transport = create_transport(client, server) self.assertEqual(client_transport.sent, 4) self.assertEqual(server_transport.sent, 4) run(client.connect()) # send data over stream client_reader, client_writer = client.create_stream() client_writer.write(b"ping") run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 5) self.assertEqual(server_transport.sent, 5) # FIXME: needs an API server_reader, server_writer = ( server.streams[0].reader, server.streams[0].writer, ) self.assertEqual(run(server_reader.read(1024)), b"ping") server_writer.write(b"pong") run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 6) self.assertEqual(server_transport.sent, 6) # client receives pong self.assertEqual(run(client_reader.read(1024)), b"pong") # client writes EOF client_writer.write_eof() run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 7) self.assertEqual(server_transport.sent, 7) # server receives EOF self.assertEqual(run(server_reader.read()), b"")
def test_create_stream(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) # client reader, writer = client.create_stream() self.assertEqual(writer.get_extra_info("stream_id"), 0) self.assertIsNotNone(writer.get_extra_info("connection")) reader, writer = client.create_stream() self.assertEqual(writer.get_extra_info("stream_id"), 4) reader, writer = client.create_stream(is_unidirectional=True) self.assertEqual(writer.get_extra_info("stream_id"), 2) reader, writer = client.create_stream(is_unidirectional=True) self.assertEqual(writer.get_extra_info("stream_id"), 6) # server reader, writer = server.create_stream() self.assertEqual(writer.get_extra_info("stream_id"), 1) reader, writer = server.create_stream() self.assertEqual(writer.get_extra_info("stream_id"), 5) reader, writer = server.create_stream(is_unidirectional=True) self.assertEqual(writer.get_extra_info("stream_id"), 3) reader, writer = server.create_stream(is_unidirectional=True) self.assertEqual(writer.get_extra_info("stream_id"), 7)
def test_connection_lost(self): client = QuicConnection(is_client=True) server = QuicConnection( is_client=False, certificate=SERVER_CERTIFICATE, private_key=SERVER_PRIVATE_KEY, ) # perform handshake client_transport, server_transport = create_transport(client, server) self.assertEqual(client_transport.sent, 4) self.assertEqual(server_transport.sent, 4) run(client.connect()) # send data over stream client_reader, client_writer = client.create_stream() client_writer.write(b"ping") run(asyncio.sleep(0)) self.assertEqual(client_transport.sent, 5) self.assertEqual(server_transport.sent, 5) # break connection client.connection_lost(None) self.assertEqual(run(client_reader.read()), b"")