def build_goaway_frame(self, last_stream_id, error_code=0): """ Builds a single GOAWAY frame. """ f = GoAwayFrame(0) f.error_code = error_code f.last_stream_id = last_stream_id return f
def test_repr(self): f = GoAwayFrame() assert repr(f).endswith( "last_stream_id=0, error_code=0, additional_data=b''") f.last_stream_id = 64 f.error_code = 32 f.additional_data = b'hello' assert repr(f).endswith( "last_stream_id=64, error_code=32, additional_data=b'hello'")
def _terminate_connection(self, error_code): """ Terminate the connection early. Used in error handling blocks to send GOAWAY frames. """ f = GoAwayFrame(0) f.last_stream_id = self.highest_inbound_stream_id f.error_code = error_code self.state_machine.process_input(ConnectionInputs.SEND_GOAWAY) self._prepare_for_sending([f])
def build_goaway_frame(self, last_stream_id, error_code=0, additional_data=b''): """ Builds a single GOAWAY frame. """ f = GoAwayFrame(0) f.error_code = error_code f.last_stream_id = last_stream_id f.additional_data = additional_data return f
def close_connection(self, error_code=0): """ Close a connection, emitting a GOAWAY frame. """ self.state_machine.process_input(ConnectionInputs.SEND_GOAWAY) f = GoAwayFrame(0) f.error_code = error_code f.last_stream_id = self.highest_stream_id self._prepare_for_sending([f]) return []
def test_goaway_serializes_properly(self): f = GoAwayFrame(0) f.last_stream_id = 64 f.error_code = 32 f.additional_data = b'hello' s = f.serialize() assert s == ( b'\x00\x00\x0D\x07\x00\x00\x00\x00\x00' + # Frame header b'\x00\x00\x00\x40' + # Last Stream ID b'\x00\x00\x00\x20' + # Error Code b'hello' # Additional data )
def test_goaway_serializes_properly(self): f = GoAwayFrame() f.last_stream_id = 64 f.error_code = 32 f.additional_data = b'hello' s = f.serialize() assert s == ( b'\x00\x00\x0D\x07\x00\x00\x00\x00\x00' + # Frame header b'\x00\x00\x00\x40' + # Last Stream ID b'\x00\x00\x00\x20' + # Error Code b'hello' # Additional data )
def close_connection(self, error_code=0): """ Close a connection, emitting a GOAWAY frame. :param error_code: (optional) The error code to send in the GOAWAY frame. :returns: Nothing """ self.state_machine.process_input(ConnectionInputs.SEND_GOAWAY) f = GoAwayFrame(0) f.error_code = error_code f.last_stream_id = self.highest_inbound_stream_id self._prepare_for_sending([f])
def receive_frame(self, frame): """ Handle a frame received on the connection. """ try: if frame.body_len > self.max_inbound_frame_size: raise ProtocolError( "Received overlong frame: length %d, max %d" % (frame.body_len, self.max_inbound_frame_size) ) # I don't love using __class__ here, maybe reconsider it. frames, events = self._frame_dispatch_table[frame.__class__](frame) except ProtocolError as e: # For whatever reason, receiving the frame caused a protocol error. # We should prepare to emit a GoAway frame before throwing the # exception up further. No need for an event: the exception will # do fine. f = GoAwayFrame(0) f.last_stream_id = sorted(self.streams.keys())[-1] f.error_code = e.error_code self.state_machine.process_input(ConnectionInputs.SEND_GOAWAY) self._prepare_for_sending([f]) raise except StreamClosedError as e: # We need to send a RST_STREAM frame on behalf of the stream. # The frame the stream wants to emit is already present in the # exception. # This does not require re-raising: it's an expected behaviour. f = RstStreamFrame(e.stream_id) f.error_code = e.error_code self._prepare_for_sending([f]) events = [] else: self._prepare_for_sending(frames) return events
def receive_frame(self, frame): """ Handle a frame received on the connection. """ try: if frame.body_len > self.max_inbound_frame_size: raise ProtocolError( "Received overlong frame: length %d, max %d" % (frame.body_len, self.max_inbound_frame_size)) # I don't love using __class__ here, maybe reconsider it. frames, events = self._frame_dispatch_table[frame.__class__](frame) except ProtocolError as e: # For whatever reason, receiving the frame caused a protocol error. # We should prepare to emit a GoAway frame before throwing the # exception up further. No need for an event: the exception will # do fine. f = GoAwayFrame(0) f.last_stream_id = sorted(self.streams.keys())[-1] f.error_code = e.error_code self.state_machine.process_input(ConnectionInputs.SEND_GOAWAY) self._prepare_for_sending([f]) raise except StreamClosedError as e: # We need to send a RST_STREAM frame on behalf of the stream. # The frame the stream wants to emit is already present in the # exception. # This does not require re-raising: it's an expected behaviour. f = RstStreamFrame(e.stream_id) f.error_code = e.error_code self._prepare_for_sending([f]) events = [] else: self._prepare_for_sending(frames) return events