Example #1
0
async def test_http2_connection_post_request():
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        hyperframe.frame.SettingsFrame().serialize(),
        hyperframe.frame.HeadersFrame(
            stream_id=1,
            data=hpack.Encoder().encode([
                (b":status", b"200"),
                (b"content-type", b"plain/text"),
            ]),
            flags=["END_HEADERS"],
        ).serialize(),
        hyperframe.frame.DataFrame(stream_id=1,
                                   data=b"Hello, world!",
                                   flags=["END_STREAM"]).serialize(),
    ])
    async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn:
        response = await conn.request(
            "POST",
            "https://example.com/",
            headers={b"content-length": b"17"},
            content=b'{"data": "upload"}',
        )
        assert response.status == 200
        assert response.content == b"Hello, world!"
Example #2
0
async def test_http2_connection_attempt_close():
    """
    A connection can only be closed when it is idle.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        hyperframe.frame.SettingsFrame().serialize(),
        hyperframe.frame.HeadersFrame(
            stream_id=1,
            data=hpack.Encoder().encode([
                (b":status", b"200"),
                (b"content-type", b"plain/text"),
            ]),
            flags=["END_HEADERS"],
        ).serialize(),
        hyperframe.frame.DataFrame(stream_id=1,
                                   data=b"Hello, world!",
                                   flags=["END_STREAM"]).serialize(),
    ])
    async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn:
        async with conn.stream("GET", "https://example.com/") as response:
            await response.aread()
            assert response.status == 200
            assert response.content == b"Hello, world!"

        await conn.aclose()
        with pytest.raises(ConnectionNotAvailable):
            await conn.request("GET", "https://example.com/")
Example #3
0
async def test_http11_connection_with_local_protocol_error():
    """
    If a local protocol error occurs, then no response will be returned,
    and the connection will not be reusable.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        b"HTTP/1.1 200 OK\r\n",
        b"Content-Type: plain/text\r\n",
        b"Content-Length: 13\r\n",
        b"\r\n",
        b"Hello, world!",
    ])
    async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn:
        with pytest.raises(LocalProtocolError) as exc_info:
            await conn.request("GET",
                               "https://example.com/",
                               headers={"Host": "\0"})

        assert str(exc_info.value) == "Illegal header value b'\\x00'"

        assert not conn.is_idle()
        assert conn.is_closed()
        assert not conn.is_available()
        assert not conn.has_expired()
        assert (
            repr(conn) ==
            "<AsyncHTTP11Connection ['https://example.com:443', CLOSED, Request Count: 1]>"
        )
Example #4
0
async def test_http2_connection():
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        hyperframe.frame.SettingsFrame().serialize(),
        hyperframe.frame.HeadersFrame(
            stream_id=1,
            data=hpack.Encoder().encode([
                (b":status", b"200"),
                (b"content-type", b"plain/text"),
            ]),
            flags=["END_HEADERS"],
        ).serialize(),
        hyperframe.frame.DataFrame(stream_id=1,
                                   data=b"Hello, world!",
                                   flags=["END_STREAM"]).serialize(),
    ])
    async with AsyncHTTP2Connection(origin=origin,
                                    stream=stream,
                                    keepalive_expiry=5.0) as conn:
        response = await conn.request("GET", "https://example.com/")
        assert response.status == 200
        assert response.content == b"Hello, world!"

        assert conn.is_idle()
        assert conn.is_available()
        assert not conn.is_closed()
        assert not conn.has_expired()
        assert (conn.info() ==
                "'https://example.com:443', HTTP/2, IDLE, Request Count: 1")
        assert (
            repr(conn) ==
            "<AsyncHTTP2Connection ['https://example.com:443', IDLE, Request Count: 1]>"
        )
Example #5
0
async def test_http11_connection_unread_response():
    """
    If the client releases the response without reading it to termination,
    then the connection will not be reusable.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        b"HTTP/1.1 200 OK\r\n",
        b"Content-Type: plain/text\r\n",
        b"Content-Length: 13\r\n",
        b"\r\n",
        b"Hello, world!",
    ])
    async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn:
        async with conn.stream("GET", "https://example.com/") as response:
            assert response.status == 200

        assert not conn.is_idle()
        assert conn.is_closed()
        assert not conn.is_available()
        assert not conn.has_expired()
        assert (
            repr(conn) ==
            "<AsyncHTTP11Connection ['https://example.com:443', CLOSED, Request Count: 1]>"
        )
Example #6
0
async def test_http2_request_to_incorrect_origin():
    """
    A connection can only send requests to whichever origin it is connected to.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([])
    async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn:
        with pytest.raises(RuntimeError):
            await conn.request("GET", "https://other.com/")
Example #7
0
async def test_http2_connection_with_remote_protocol_error():
    """
    If a remote protocol error occurs, then no response will be returned,
    and the connection will not be reusable.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([b"Wait, this isn't valid HTTP!", b""])
    async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn:
        with pytest.raises(RemoteProtocolError):
            await conn.request("GET", "https://example.com/")
Example #8
0
async def test_http11_connection_attempt_close():
    """
    A connection can only be closed when it is idle.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        b"HTTP/1.1 200 OK\r\n",
        b"Content-Type: plain/text\r\n",
        b"Content-Length: 13\r\n",
        b"\r\n",
        b"Hello, world!",
    ])
    async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn:
        async with conn.stream("GET", "https://example.com/") as response:
            await response.aread()
            assert response.status == 200
            assert response.content == b"Hello, world!"
Example #9
0
async def test_http11_connection_handles_one_active_request():
    """
    Attempting to send a request while one is already in-flight will raise
    a ConnectionNotAvailable exception.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        b"HTTP/1.1 200 OK\r\n",
        b"Content-Type: plain/text\r\n",
        b"Content-Length: 13\r\n",
        b"\r\n",
        b"Hello, world!",
    ])
    async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn:
        async with conn.stream("GET", "https://example.com/"):
            with pytest.raises(ConnectionNotAvailable):
                await conn.request("GET", "https://example.com/")
Example #10
0
async def test_http11_connection_with_remote_protocol_error():
    """
    If a remote protocol error occurs, then no response will be returned,
    and the connection will not be reusable.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([b"Wait, this isn't valid HTTP!", b""])
    async with AsyncHTTP11Connection(origin=origin, stream=stream) as conn:
        with pytest.raises(RemoteProtocolError):
            await conn.request("GET", "https://example.com/")

        assert not conn.is_idle()
        assert conn.is_closed()
        assert not conn.is_available()
        assert not conn.has_expired()
        assert (
            repr(conn) ==
            "<AsyncHTTP11Connection ['https://example.com:443', CLOSED, Request Count: 1]>"
        )
Example #11
0
async def test_http2_connection_with_rst_stream():
    """
    If a stream reset occurs, then no response will be returned,
    but the connection will remain reusable for other requests.
    """
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        hyperframe.frame.SettingsFrame().serialize(),
        hyperframe.frame.HeadersFrame(
            stream_id=1,
            data=hpack.Encoder().encode([
                (b":status", b"200"),
                (b"content-type", b"plain/text"),
            ]),
            flags=["END_HEADERS"],
        ).serialize(),
        # Stream is closed midway through the first response...
        hyperframe.frame.RstStreamFrame(stream_id=1, error_code=8).serialize(),
        # ...Which doesn't prevent the second response.
        hyperframe.frame.HeadersFrame(
            stream_id=3,
            data=hpack.Encoder().encode([
                (b":status", b"200"),
                (b"content-type", b"plain/text"),
            ]),
            flags=["END_HEADERS"],
        ).serialize(),
        hyperframe.frame.DataFrame(stream_id=3,
                                   data=b"Hello, world!",
                                   flags=["END_STREAM"]).serialize(),
        b"",
    ])
    async with AsyncHTTP2Connection(origin=origin, stream=stream) as conn:
        with pytest.raises(RemoteProtocolError):
            await conn.request("GET", "https://example.com/")
        response = await conn.request("GET", "https://example.com/")
        assert response.status == 200
Example #12
0
async def test_http11_connection():
    origin = Origin(b"https", b"example.com", 443)
    stream = AsyncMockStream([
        b"HTTP/1.1 200 OK\r\n",
        b"Content-Type: plain/text\r\n",
        b"Content-Length: 13\r\n",
        b"\r\n",
        b"Hello, world!",
    ])
    async with AsyncHTTP11Connection(origin=origin,
                                     stream=stream,
                                     keepalive_expiry=5.0) as conn:
        response = await conn.request("GET", "https://example.com/")
        assert response.status == 200
        assert response.content == b"Hello, world!"

        assert conn.is_idle()
        assert not conn.is_closed()
        assert conn.is_available()
        assert not conn.has_expired()
        assert (
            repr(conn) ==
            "<AsyncHTTP11Connection ['https://example.com:443', IDLE, Request Count: 1]>"
        )