Пример #1
0
    def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb):
        super(Http2Worker, self).__init__(logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb)

        self.network_buffer_size = 128 * 1024

        # Google http/2 time out is 4 mins.
        self.ssl_sock.settimeout(240)
        self._sock = BufferedSocket(ssl_sock, self.network_buffer_size)

        self.next_stream_id = 1
        self.streams = {}
        self.last_ping_time = time.time()
        self.last_active_time = self.ssl_sock.create_time - 1
        self.continue_timeout = 0

        # count ping not ACK
        # increase when send ping
        # decrease when recv ping ack
        # if this in not 0, don't accept request.
        self.ping_on_way = 0
        self.accept_task = False

        # request_lock
        self.request_lock = threading.Lock()

        # all send frame must put to this queue
        # then send by send_loop
        # every frame put to this queue must allowed by stream window and connection window
        # any data frame blocked by connection window should put to self.blocked_send_frames
        self.send_queue = Queue.Queue()

        # keep blocked data frame in this buffer
        # which is allowed by stream window but blocked by connection window.
        # They will be sent when connection window open
        self.blocked_send_frames = []

        # Values for the settings used on an HTTP/2 connection.
        # will send to remote using Setting Frame
        self.local_settings = {
            SettingsFrame.INITIAL_WINDOW_SIZE: 16 * 1024 * 1024,
            SettingsFrame.SETTINGS_MAX_FRAME_SIZE: 256 * 1024
        }
        self.local_connection_initial_windows = 32 * 1024 * 1024
        self.local_window_manager = FlowControlManager(self.local_connection_initial_windows)

        # changed by server, with SettingFrame
        self.remote_settings = {
            SettingsFrame.INITIAL_WINDOW_SIZE: DEFAULT_WINDOW_SIZE,
            SettingsFrame.SETTINGS_MAX_FRAME_SIZE: DEFAULT_MAX_FRAME,
            SettingsFrame.MAX_CONCURRENT_STREAMS: 100
        }

        #self.remote_window_size = DEFAULT_WINDOW_SIZE
        self.remote_window_size = 32 * 1024 * 1024

        # send Setting frame before accept task.
        self._send_preamble()

        threading.Thread(target=self.send_loop).start()
        threading.Thread(target=self.recv_loop).start()
Пример #2
0
    def test_socket_error_on_readline(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)

        with pytest.raises(ConnectionResetError):
            b.readline()
Пример #3
0
    def test_can_create_buffered_sockets(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)

        assert b is not None
        assert b._buffer_size == 1000
Пример #4
0
    def test_can_send_on_buffered_socket(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)
        b.send(b'test data')

        assert len(s.outbound_packets) == 1
        assert s.outbound_packets[0] == b'test data'
Пример #5
0
    def test_receive_single_packet(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets.append(b'test data')

        d = b.recv(100).tobytes()
        assert d == b'test data'
Пример #6
0
    def test_oversized_read(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets.append(b'a' * 600)

        d = b.recv(1200).tobytes()
        assert d == b'a' * 600
Пример #7
0
    def test_socket_fill_resizes_if_needed(self):
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets = [b'Here']
        b._index = 1000

        assert not len(b.buffer)

        b.fill()
        assert len(b.buffer) == 4
        assert b._index == 0
Пример #8
0
    def test_socket_readline_too_long(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)

        b._buffer_view[0:b._buffer_size] = b'0' * b._buffer_size
        b._bytes_in_buffer = b._buffer_size

        with pytest.raises(LineTooLongError):
            b.readline()
Пример #9
0
    def test_advancing_sockets(self):
        s = DummySocket()
        b = BufferedSocket(s)
        b._buffer_view[0:5] = b'abcde'
        b._bytes_in_buffer += 5

        assert len(b.buffer) == 5

        b.advance_buffer(3)
        assert len(b.buffer) == 2

        assert b.buffer.tobytes() == b'de'
Пример #10
0
    def test_receive_small_packets(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets = [b'Here', b'begins', b'the', b'test', b'data']

        d = b''
        for _ in range(5):
            d += b.recv(100).tobytes()

        assert d == b'Herebeginsthetestdata'
Пример #11
0
    def test_filling_the_buffer(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets = [
            b'a' * 1000,
            b'a' * 800,
        ]

        d = b''
        for _ in range(2):
            d += b.recv(900).tobytes()

        assert d == (b'a' * 1800)
Пример #12
0
    def test_receive_multiple_packets_at_once(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets = [
            b'Here', b'begins', b'the', b'test', b'data', b'!'
        ]
        s.read_count = 3

        d = b''
        for _ in range(22):
            d += b.recv(1).tobytes()

        assert d == b'Herebeginsthetestdata!'
Пример #13
0
    def test_socket_fill_basic(self):
        s = DummySocket()
        b = BufferedSocket(s)
        s.inbound_packets = [b'Here', b'begins', b'the']

        assert not len(b.buffer)

        b.fill()
        assert len(b.buffer) == 4

        b.fill()
        assert len(b.buffer) == 10

        b.fill()
        assert len(b.buffer) == 13
Пример #14
0
    def test_readline_from_buffer(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)

        one = b'hi there\r\n'
        two = b'this is another line\r\n'
        three = b'\r\n'
        combined = b''.join([one, two, three])
        b._buffer_view[0:len(combined)] = combined
        b._bytes_in_buffer += len(combined)

        assert b.readline().tobytes() == one
        assert b.readline().tobytes() == two
        assert b.readline().tobytes() == three
Пример #15
0
    def test_readline_from_socket(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)

        one = b'hi there\r\n'
        two = b'this is another line\r\n'
        three = b'\r\n'
        combined = b''.join([one, two, three])

        for i in range(0, len(combined), 5):
            s.inbound_packets.append(combined[i:i + 5])

        assert b.readline().tobytes() == one
        assert b.readline().tobytes() == two
        assert b.readline().tobytes() == three
Пример #16
0
    def connect(self):
        """
        Connect to the server specified when the object was created. This is a
        no-op if we're already connected.

        Concurrency
        -----------

        This method is thread-safe. It may be called from multiple threads, and
        is a noop for all threads apart from the first.

        :returns: Nothing.

        """
        #print("connecting to ATS")
        with self._lock:
            if self._sock is not None:
                return
            sni = self.host
            if not self.proxy_host:
                host = self.host
                port = self.port
            else:
                host = self.proxy_host
                port = self.proxy_port

            sock = socket.create_connection((host, port))

            if self.secure:
                #assert not self.proxy_host, "Proxy with HTTPS not supported."
                sock, proto = wrap_socket(sock,
                                          sni,
                                          self.ssl_context,
                                          force_proto=self.force_proto)
            else:
                proto = H2C_PROTOCOL

            log.debug("Selected NPN protocol: %s", proto)
            assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL

            self._sock = BufferedSocket(sock, self.network_buffer_size)

            self._send_preamble()
Пример #17
0
    def test_readline_both(self, monkeypatch):
        monkeypatch.setattr(hyper.common.bufsocket.select, 'select',
                            dummy_select)
        s = DummySocket()
        b = BufferedSocket(s)

        one = b'hi there\r\n'
        two = b'this is another line\r\n'
        three = b'\r\n'
        combined = b''.join([one, two, three])

        split_index = int(len(combined) / 2)

        b._buffer_view[0:split_index] = combined[0:split_index]
        b._bytes_in_buffer += split_index

        for i in range(split_index, len(combined), 5):
            s.inbound_packets.append(combined[i:i + 5])

        assert b.readline().tobytes() == one
        assert b.readline().tobytes() == two
        assert b.readline().tobytes() == three
Пример #18
0
    def test_socket_fill_raises_connection_errors(self):
        s = DummySocket()
        b = BufferedSocket(s)

        with pytest.raises(ConnectionResetError):
            b.fill()