Beispiel #1
0
    def receive_frame(self, 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.
            error_string = frame._extra_info()
            time_cost = time.time() - self.last_recv_time
            if frame.additional_data != "session_timed_out":
                self.logger.warn("goaway:%s, t:%d", error_string, time_cost)

            self.close("GoAway:%s inactive time:%d" % (error_string, time_cost))

        elif frame.type == BlockedFrame.type:
            self.logger.warn("%s get BlockedFrame", self.ip_str)
        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)
Beispiel #2
0
 def send_ping(self):
     # Use less for GAE server.
     p = PingFrame(0)
     p.opaque_data = struct.pack("!d", time.time())
     self.send_queue.put(p)
     self.last_ping_time = time.time()
     self.ping_on_way += 1
Beispiel #3
0
    def receive_frame(self, 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.
            error_string = frame._extra_info()
            time_cost = time.time() - self.last_recv_time
            if frame.additional_data != "session_timed_out":
                self.logger.warn("goaway:%s, t:%d", error_string, time_cost)

            self.close("GoAway:%s inactive time:%d" % (error_string, time_cost))

        elif frame.type == BlockedFrame.type:
            self.logger.warn("%s get BlockedFrame", self.ip)
        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, 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, 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 send_ping(self):
     # Use less for GAE server.
     p = PingFrame(0)
     p.opaque_data = struct.pack("!d", time.time())
     self.send_queue.put(p)
     self.last_ping_time = time.time()
     self.ping_on_way += 1
Beispiel #6
0
    def test_ping_with_ack_ignored(self):
        c = HTTP20Connection('www.google.com')
        f = PingFrame(0)
        f.flags = set(['ACK'])
        f.opaque_data = b'12345678'

        def data_cb(frame, tolerate_peer_gone=False):
            assert False, 'should not be called'
        c._send_cb = data_cb
        c.receive_frame(f)
Beispiel #7
0
    def test_ping_with_ack_ignored(self):
        c = HTTP20Connection('www.google.com')
        f = PingFrame(0)
        f.flags = set(['ACK'])
        f.opaque_data = b'12345678'

        def data_cb(frame, tolerate_peer_gone=False):
            assert False, 'should not be called'

        c._send_cb = data_cb
        c.receive_frame(f)
Beispiel #8
0
    def test_ping_without_ack_gets_reply(self):
        c = HTTP20Connection('www.google.com')
        f = PingFrame(0)
        f.opaque_data = b'12345678'

        frames = []

        def data_cb(frame, tolerate_peer_gone=False):
            frames.append(frame)
        c._send_cb = data_cb
        c.receive_frame(f)

        assert len(frames) == 1
        assert frames[0].type == PingFrame.type
        assert frames[0].flags == set(['ACK'])
        assert frames[0].opaque_data == b'12345678'
Beispiel #9
0
    def test_ping_without_ack_gets_reply(self):
        c = HTTP20Connection('www.google.com')
        f = PingFrame(0)
        f.opaque_data = b'12345678'

        frames = []

        def data_cb(frame, tolerate_peer_gone=False):
            frames.append(frame)

        c._send_cb = data_cb
        c.receive_frame(f)

        assert len(frames) == 1
        assert frames[0].type == PingFrame.type
        assert frames[0].flags == set(['ACK'])
        assert frames[0].opaque_data == b'12345678'