def test_seek(self): buf = Buffer(data=b"01234567") self.assertFalse(buf.eof()) self.assertEqual(buf.tell(), 0) buf.seek(4) self.assertFalse(buf.eof()) self.assertEqual(buf.tell(), 4) buf.seek(8) self.assertTrue(buf.eof()) self.assertEqual(buf.tell(), 8)
def test_datagram_received_wrong_version(self): client = QuicConnection(is_client=True) client_transport = FakeTransport() client.connection_made(client_transport) self.assertEqual(client_transport.sent, 1) buf = Buffer(capacity=1300) push_quic_header( buf, QuicHeader( version=0xFF000011, # DRAFT_16 packet_type=PACKET_TYPE_INITIAL | (PACKET_NUMBER_SEND_SIZE - 1), destination_cid=client.host_cid, source_cid=client.peer_cid, ), ) buf.seek(1300) client.datagram_received(buf.data, None) self.assertEqual(client_transport.sent, 1)
def test_seek(self): buf = Buffer(data=b"01234567") self.assertFalse(buf.eof()) self.assertEqual(buf.tell(), 0) buf.seek(4) self.assertFalse(buf.eof()) self.assertEqual(buf.tell(), 4) buf.seek(8) self.assertTrue(buf.eof()) self.assertEqual(buf.tell(), 8) with self.assertRaises(BufferReadError): buf.seek(-1) self.assertEqual(buf.tell(), 8) with self.assertRaises(BufferReadError): buf.seek(9) self.assertEqual(buf.tell(), 8)
def _receive_stream_data_uni(self, stream: H3Stream, data: bytes, stream_ended: bool) -> List[H3Event]: http_events: List[H3Event] = [] stream.buffer += data if stream_ended: stream.ended = True buf = Buffer(data=stream.buffer) consumed = 0 unblocked_streams: Set[int] = set() while stream.stream_type == StreamType.PUSH or not buf.eof(): # fetch stream type for unidirectional streams if stream.stream_type is None: try: stream.stream_type = buf.pull_uint_var() except BufferReadError: break consumed = buf.tell() # check unicity if stream.stream_type == StreamType.CONTROL: if self._peer_control_stream_id is not None: raise StreamCreationError( "Only one control stream is allowed") self._peer_control_stream_id = stream.stream_id elif stream.stream_type == StreamType.QPACK_DECODER: if self._peer_decoder_stream_id is not None: raise StreamCreationError( "Only one QPACK decoder stream is allowed") self._peer_decoder_stream_id = stream.stream_id elif stream.stream_type == StreamType.QPACK_ENCODER: if self._peer_encoder_stream_id is not None: raise StreamCreationError( "Only one QPACK encoder stream is allowed") self._peer_encoder_stream_id = stream.stream_id if stream.stream_type == StreamType.CONTROL: # fetch next frame try: frame_type = buf.pull_uint_var() frame_length = buf.pull_uint_var() frame_data = buf.pull_bytes(frame_length) except BufferReadError: break consumed = buf.tell() self._handle_control_frame(frame_type, frame_data) elif stream.stream_type == StreamType.PUSH: # fetch push id if stream.push_id is None: try: stream.push_id = buf.pull_uint_var() except BufferReadError: break consumed = buf.tell() # remove processed data from buffer stream.buffer = stream.buffer[consumed:] return self._receive_request_or_push_data( stream, b"", stream_ended) elif stream.stream_type == StreamType.QPACK_DECODER: # feed unframed data to decoder data = buf.pull_bytes(buf.capacity - buf.tell()) consumed = buf.tell() try: self._encoder.feed_decoder(data) except pylsqpack.DecoderStreamError as exc: raise QpackDecoderStreamError() from exc self._decoder_bytes_received += len(data) elif stream.stream_type == StreamType.QPACK_ENCODER: # feed unframed data to encoder data = buf.pull_bytes(buf.capacity - buf.tell()) consumed = buf.tell() try: unblocked_streams.update(self._decoder.feed_encoder(data)) except pylsqpack.EncoderStreamError as exc: raise QpackEncoderStreamError() from exc self._encoder_bytes_received += len(data) else: # unknown stream type, discard data buf.seek(buf.capacity) consumed = buf.tell() # remove processed data from buffer stream.buffer = stream.buffer[consumed:] # process unblocked streams for stream_id in unblocked_streams: stream = self._stream[stream_id] # resume headers http_events.extend( self._handle_request_or_push_frame( frame_type=FrameType.HEADERS, frame_data=None, stream=stream, stream_ended=stream.ended and not stream.buffer, )) stream.blocked = False stream.blocked_frame_size = None # resume processing if stream.buffer: http_events.extend( self._receive_request_or_push_data(stream, b"", stream.ended)) return http_events