def receive_frame(self, frame): #self.logger.debug("h2conn recv:%s", frame) if frame.type == WindowUpdateFrame.type: # self.logger.debug("WindowUpdateFrame %d", frame.window_increment) self.increase_remote_window_size(frame.window_increment) elif frame.type == PingFrame.type: if 'ACK' in frame.flags: ping_time = struct.unpack("!d", frame.opaque_data)[0] time_now = time.time() rtt = (time_now - ping_time) * 1000 if rtt < 0: self.logger.error("rtt:%f ping_time:%f now:%f", rtt, ping_time, time_now) self.rtt = rtt self.ping_on_way -= 1 #self.logger.debug("RTT:%d, on_way:%d", self.rtt, self.ping_on_way) if self.keep_running and self.ping_on_way == 0: self.accept_task = True else: # The spec requires us to reply with PING+ACK and identical data. p = PingFrame(0) p.flags.add('ACK') p.opaque_data = frame.opaque_data self._send_cb(p) elif frame.type == SettingsFrame.type: if 'ACK' not in frame.flags: # send ACK as soon as possible f = SettingsFrame(0) f.flags.add('ACK') self._send_cb(f) # this may trigger send DataFrame blocked by remote window self._update_settings(frame) else: self.accept_task = True self.idle_cb() elif frame.type == GoAwayFrame.type: # If we get GoAway with error code zero, we are doing a graceful # shutdown and all is well. Otherwise, throw an exception. # If an error occured, try to read the error description from # code registry otherwise use the frame's additional data. time_cost = time.time() - self.last_recv_time self.close("GoAway:%s inactive time:%s" % ("conn close", time_cost)) elif frame.type in FRAMES: # This frame isn't valid at this point. #raise ValueError("Unexpected frame %s." % frame) self.logger.error("%s Unexpected frame %s.", self.ip_str, frame) else: # pragma: no cover # Unexpected frames belong to extensions. Just drop it on the # floor, but log so that users know that something happened. self.logger.error("%s Received unknown frame, type %d", self.ip_str, frame.type)
def send_ping(self): p = PingFrame(0) p.opaque_data = struct.pack("!d", time.time()) #self.send_queue.put(p) self._send_cb(p) self.last_ping_time = time.time() self.ping_on_way += 1
def test_ping_frame_serializes_properly(self): f = PingFrame(0) f.parse_flags(0xFF) f.opaque_data = b'\x01\x02' s = f.serialize() assert s == ( b'\x00\x00\x08\x06\x01\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00\x00' )
def build_ping_frame(self, ping_data, flags=None): """ Builds a single Ping frame. """ f = PingFrame(0) f.opaque_data = ping_data if flags: f.flags = set(flags) return f
def ping(self, opaque_data): """ Send a PING frame. :param opaque_data: A bytestring of length 8 that will be sent in the PING frame. :returns: Nothing """ if not isinstance(opaque_data, bytes) or len(opaque_data) != 8: raise ValueError("Invalid value for ping data: %r" % opaque_data) self.state_machine.process_input(ConnectionInputs.SEND_PING) f = PingFrame(0) f.opaque_data = opaque_data self._prepare_for_sending([f])
def _receive_ping_frame(self, frame): """ Receive a PING frame on the connection. """ events = self.state_machine.process_input(ConnectionInputs.RECV_PING) flags = [] if "ACK" in frame.flags: evt = PingAcknowledged() evt.ping_data = frame.opaque_data events.append(evt) else: f = PingFrame(0) f.flags = set(["ACK"]) f.opaque_data = frame.opaque_data flags.append(f) return flags, events
def _receive_ping_frame(self, frame): """ Receive a PING frame on the connection. """ events = self.state_machine.process_input(ConnectionInputs.RECV_PING) flags = [] if 'ACK' in frame.flags: evt = PingAcknowledged() evt.ping_data = frame.opaque_data events.append(evt) else: f = PingFrame(0) f.flags = set(['ACK']) f.opaque_data = frame.opaque_data flags.append(f) return flags, events
def test_ping_frame_serializes_properly(self): f = PingFrame() f.parse_flags(0xFF) f.opaque_data = b'\x01\x02' s = f.serialize() assert s == ( b'\x00\x00\x08\x06\x01\x00\x00\x00\x00\x01\x02\x00\x00\x00\x00\x00' b'\x00')
def test_no_more_than_8_octets(self): f = PingFrame() f.opaque_data = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09' with pytest.raises(ValueError): f.serialize()
def test_repr(self): f = PingFrame() assert repr(f).endswith("opaque_data=b''") f.opaque_data = b'hello' assert repr(f).endswith("opaque_data=b'hello'")
def test_ping_frame_has_no_more_than_body_length_8(self): f = PingFrame(0) with pytest.raises(ValueError): f.parse_body(b'\x01\x02\x03\x04\x05\x06\x07\x08\x09')
def test_no_more_than_8_octets(self): f = PingFrame(0) f.opaque_data = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09' with pytest.raises(ValueError): f.serialize()
def test_ping_frame_never_has_a_stream(self): with pytest.raises(InvalidDataError): PingFrame(1)
def test_ping_frame_has_only_one_flag(self): f = PingFrame(0) flags = f.parse_flags(0xFF) assert flags == set(['ACK'])
def test_ping_frame_has_no_less_than_body_length_8(self): f = PingFrame() with pytest.raises(ValueError): f.parse_body(b'\x01\x02\x03\x04\x05\x06\x07')
def test_ping_frame_never_has_a_stream(self): with pytest.raises(ValueError): PingFrame(stream_id=1)
def test_ping_frame_has_no_more_than_body_length_8(self): f = PingFrame() with pytest.raises(InvalidFrameError): f.parse_body(b'\x01\x02\x03\x04\x05\x06\x07\x08\x09')
def test_ping_frame_has_only_one_flag(self): f = PingFrame() flags = f.parse_flags(0xFF) assert flags == set(['ACK'])