Exemplo n.º 1
0
    def send_duplicate_push (self, stream_id, push_id):
        assert not self._is_client, "Only servers may send a duplicate push."
        assert push_id < self._max_push_id, "Given push ID is never sent"
        assert (
            push_id not in self._canceled_push_ids
        ), "Given push ID is canceled by client"

        self._quic.send_stream_data (stream_id, encode_frame(FrameType.DUPLICATE_PUSH, encode_uint_var(push_id)), True)
Exemplo n.º 2
0
    def shutdown (self, last_stream_id = None):
        assert not self._is_client, "Client must not send a goaway frame"
        if last_stream_id is None:
            last_stream_id = self._max_client_bidi_stream_id

        else:
            if last_stream_id == -1:
                last_stream_id = -4
            assert last_stream_id % 4 == 0 and (-4 <= last_stream_id <= self._max_client_bidi_stream_id), "Unissued request stream"

        frame = encode_frame(FrameType.GOAWAY, encode_uint_var(last_stream_id + 4))
        self._quic.send_stream_data (self._local_control_stream_id, frame)
Exemplo n.º 3
0
    def test_handle_request_frame_bad_headers(self):
        """
        We should not receive HEADERS which cannot be decoded.
        """
        quic_server = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=False))
        h3_server = H3Connection(quic_server)

        h3_server.handle_event(
            StreamDataReceived(stream_id=0,
                               data=encode_frame(FrameType.HEADERS, b""),
                               end_stream=False))
        self.assertEqual(quic_server.closed,
                         (ErrorCode.HTTP_QPACK_DECOMPRESSION_FAILED, ""))
Exemplo n.º 4
0
    def send_push_promise (self, stream_id, headers):
        assert not self._is_client, "Only servers may send a push promise."
        if self._max_push_id is None or self._next_push_id >= self._max_push_id:
            raise NoAvailablePushIDError
        push_id = self._next_push_id
        self._next_push_id += 1

        frame = encode_frame (FrameType.PUSH_PROMISE, encode_uint_var(push_id) + self._encode_headers(stream_id, headers))
        self._quic.send_stream_data (stream_id, frame)

        push_stream_id = self._create_uni_stream (StreamType.PUSH)
        self._quic.send_stream_data (push_stream_id, encode_uint_var(push_id))
        self._push_map [push_stream_id] = push_id
        return push_stream_id
Exemplo n.º 5
0
    def test_handle_request_frame_wrong_frame_type(self):
        quic_server = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=False))
        h3_server = H3Connection(quic_server)

        h3_server.handle_event(
            StreamDataReceived(
                stream_id=0,
                data=encode_frame(FrameType.SETTINGS, b""),
                end_stream=False,
            ))
        self.assertEqual(
            quic_server.closed,
            (ErrorCode.HTTP_FRAME_UNEXPECTED,
             "Invalid frame type on request stream"),
        )
Exemplo n.º 6
0
    def test_handle_request_frame_push_promise_from_client(self):
        """
        A server should not receive PUSH_PROMISE on a request stream.
        """
        quic_server = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=False))
        h3_server = H3Connection(quic_server)

        h3_server.handle_event(
            StreamDataReceived(
                stream_id=0,
                data=encode_frame(FrameType.PUSH_PROMISE, b""),
                end_stream=False,
            ))
        self.assertEqual(
            quic_server.closed,
            (ErrorCode.HTTP_FRAME_UNEXPECTED,
             "Clients must not send PUSH_PROMISE"),
        )
Exemplo n.º 7
0
    def test_handle_request_frame_data_before_headers(self):
        """
        We should not receive DATA before receiving headers.
        """
        quic_server = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=False))
        h3_server = H3Connection(quic_server)

        h3_server.handle_event(
            StreamDataReceived(stream_id=0,
                               data=encode_frame(FrameType.DATA, b""),
                               end_stream=False))
        self.assertEqual(
            quic_server.closed,
            (
                ErrorCode.HTTP_FRAME_UNEXPECTED,
                "DATA frame is not allowed in this state",
            ),
        )
Exemplo n.º 8
0
    def test_handle_control_frame_max_push_id_from_server(self):
        """
        A client should not receive MAX_PUSH_ID on the control stream.
        """
        quic_client = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=True))
        h3_client = H3Connection(quic_client)

        h3_client.handle_event(
            StreamDataReceived(
                stream_id=3,
                data=encode_uint_var(StreamType.CONTROL) +
                encode_frame(FrameType.MAX_PUSH_ID, b""),
                end_stream=False,
            ))
        self.assertEqual(
            quic_client.closed,
            (ErrorCode.HTTP_FRAME_UNEXPECTED,
             "Servers must not send MAX_PUSH_ID"),
        )
Exemplo n.º 9
0
    def test_handle_control_frame_headers(self):
        """
        We should not receive HEADERS on the control stream.
        """
        quic_server = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=False))
        h3_server = H3Connection(quic_server)

        h3_server.handle_event(
            StreamDataReceived(
                stream_id=2,
                data=encode_uint_var(StreamType.CONTROL) +
                encode_frame(FrameType.HEADERS, b""),
                end_stream=False,
            ))
        self.assertEqual(
            quic_server.closed,
            (ErrorCode.HTTP_FRAME_UNEXPECTED,
             "Invalid frame type on control stream"),
        )
Exemplo n.º 10
0
    def test_handle_push_frame_wrong_frame_type(self):
        """
        We should not received SETTINGS on a push stream.
        """
        quic_client = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=True))
        h3_client = H3Connection(quic_client)

        h3_client.handle_event(
            StreamDataReceived(
                stream_id=15,
                data=encode_uint_var(StreamType.PUSH) +
                encode_uint_var(0)  # push ID
                + encode_frame(FrameType.SETTINGS, b""),
                end_stream=False,
            ))
        self.assertEqual(
            quic_client.closed,
            (ErrorCode.HTTP_FRAME_UNEXPECTED,
             "Invalid frame type on push stream"),
        )
Exemplo n.º 11
0
    def test_handle_request_frame_headers_after_trailers(self):
        """
        We should not receive HEADERS after receiving trailers.
        """
        quic_client = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=True))
        quic_server = FakeQuicConnection(configuration=QuicConfiguration(
            is_client=False))

        h3_client = H3Connection(quic_client)
        h3_server = H3Connection(quic_server)

        stream_id = quic_client.get_next_available_stream_id()
        h3_client.send_headers(
            stream_id=stream_id,
            headers=[
                (b":method", b"GET"),
                (b":scheme", b"https"),
                (b":authority", b"localhost"),
                (b":path", b"/"),
            ],
        )
        h3_client.send_headers(stream_id=stream_id,
                               headers=[(b"x-some-trailer", b"foo")],
                               end_stream=True)
        h3_transfer(quic_client, h3_server)

        h3_server.handle_event(
            StreamDataReceived(stream_id=0,
                               data=encode_frame(FrameType.HEADERS, b""),
                               end_stream=False))
        self.assertEqual(
            quic_server.closed,
            (
                ErrorCode.HTTP_FRAME_UNEXPECTED,
                "HEADERS frame is not allowed in this state",
            ),
        )
Exemplo n.º 12
0
 def cancel_push (self, push_id):
     self._canceled_push_ids.add (push_id)
     self._quic.send_stream_data (self._local_control_stream_id, encode_frame(FrameType.CANCEL_PUSH, encode_uint_var(push_id)))