예제 #1
0
async def test_handle_end_body(stream: HTTPStream) -> None:
    stream.app_put = AsyncMock()
    await stream.handle(EndBody(stream_id=1))
    stream.app_put.assert_called()
    assert stream.app_put.call_args_list == [
        call({"type": "http.request", "body": b"", "more_body": False})
    ]
예제 #2
0
async def test_send_reject(stream: WSStream) -> None:
    await stream.handle(
        Request(
            stream_id=1,
            http_version="2",
            headers=[(b"sec-websocket-version", b"13")],
            raw_path=b"/",
            method="GET",
        ))
    await stream.app_send(
        cast(
            WebsocketResponseStartEvent,
            {
                "type": "websocket.http.response.start",
                "status": 200,
                "headers": []
            },
        ), )
    assert stream.state == ASGIWebsocketState.HANDSHAKE
    # Must wait for response before sending anything
    stream.send.assert_not_called()  # type: ignore
    await stream.app_send(
        cast(WebsocketResponseBodyEvent, {
            "type": "websocket.http.response.body",
            "body": b"Body"
        }))
    assert stream.state == ASGIWebsocketState.HTTPCLOSED
    stream.send.assert_called()  # type: ignore
    assert stream.send.call_args_list == [  # type: ignore
        call(Response(stream_id=1, headers=[], status_code=200)),
        call(Body(stream_id=1, data=b"Body")),
        call(EndBody(stream_id=1)),
    ]
    stream.config._log.access.assert_called()  # type: ignore
예제 #3
0
async def test_send_response(stream: HTTPStream) -> None:
    await stream.handle(
        Request(stream_id=1,
                http_version="2",
                headers=[],
                raw_path=b"/?a=b",
                method="GET"))
    await stream.app_send(
        cast(HTTPResponseStartEvent, {
            "type": "http.response.start",
            "status": 200,
            "headers": []
        }))
    assert stream.state == ASGIHTTPState.REQUEST
    # Must wait for response before sending anything
    stream.send.assert_not_called()  # type: ignore
    await stream.app_send(
        cast(HTTPResponseBodyEvent, {
            "type": "http.response.body",
            "body": b"Body"
        }))
    assert stream.state == ASGIHTTPState.CLOSED
    stream.send.assert_called()  # type: ignore
    assert stream.send.call_args_list == [  # type: ignore
        call(Response(stream_id=1, headers=[], status_code=200)),
        call(Body(stream_id=1, data=b"Body")),
        call(EndBody(stream_id=1)),
        call(StreamClosed(stream_id=1)),
    ]
    stream.config._log.access.assert_called()  # type: ignore
예제 #4
0
async def test_protocol_handle_data_post_response(
        protocol: H11Protocol) -> None:
    await protocol.handle(
        RawData(data=b"POST / HTTP/1.1\r\nHost: hypercorn\r\n"))
    await protocol.stream_send(
        Response(stream_id=1, status_code=201, headers=[]))
    await protocol.stream_send(EndBody(stream_id=1))
    await protocol.handle(RawData(data=b"abcd\r\n\r\n"))
예제 #5
0
async def test_protocol_handle_data_post_close(protocol: H11Protocol) -> None:
    await protocol.handle(
        RawData(data=b"POST / HTTP/1.1\r\nHost: hypercorn\r\nContent-Length: 10\r\n")
    )
    await protocol.stream_send(Response(stream_id=1, status_code=201, headers=[]))
    await protocol.stream_send(EndBody(stream_id=1))
    # Key is that this doesn't error
    await protocol.handle(RawData(data=b"abcdefghij"))
예제 #6
0
async def test_protocol_instant_recycle(protocol: H11Protocol) -> None:
    data = b"GET / HTTP/1.1\r\nHost: hypercorn\r\n\r\n"
    await protocol.handle(RawData(data=data))
    assert protocol.stream is not None
    await protocol.stream_send(Response(stream_id=1, status_code=200, headers=[]))
    await protocol.stream_send(EndBody(stream_id=1))
    await protocol.handle(RawData(data=data))
    await protocol.stream_send(StreamClosed(stream_id=1))
    # Should have recycled, i.e. a stream should exist
    assert protocol.stream is not None
예제 #7
0
async def test_protocol_send_stream_closed(keep_alive: bool, expected: Any,
                                           protocol: H11Protocol) -> None:
    data = b"GET / HTTP/1.1\r\nHost: hypercorn\r\n"
    if keep_alive:
        data += b"\r\n"
    else:
        data += b"Connection: close\r\n\r\n"
    await protocol.handle(RawData(data=data))
    await protocol.stream_send(
        Response(stream_id=1, status_code=200, headers=[]))
    await protocol.stream_send(EndBody(stream_id=1))
    await protocol.stream_send(StreamClosed(stream_id=1))
    protocol.send.assert_called()
    assert protocol.send.call_args_list[2] == call(expected)
예제 #8
0
async def test_protocol_instant_recycle(protocol: H11Protocol) -> None:
    data = b"GET / HTTP/1.1\r\nHost: hypercorn\r\n\r\n"
    # This test requires a real event as the handling should pause on
    # the instant receipt
    protocol.can_read = EventWrapper()
    await protocol.handle(RawData(data=data))
    assert protocol.stream is not None
    await protocol.stream_send(
        Response(stream_id=1, status_code=200, headers=[]))
    await protocol.stream_send(EndBody(stream_id=1))
    task = asyncio.ensure_future(protocol.handle(RawData(data=data)))
    await asyncio.sleep(0)  # Switch to task
    await protocol.stream_send(StreamClosed(stream_id=1))
    # Should have recycled, i.e. a stream should exist
    assert protocol.stream is not None
    await asyncio.sleep(0)  # Switch to task
    assert task.done()
예제 #9
0
async def test_protocol_handle_request(protocol: H11Protocol) -> None:
    client = h11.Connection(h11.CLIENT)
    await protocol.handle(
        RawData(data=client.send(
            h11.Request(method="GET", target="/?a=b", headers=BASIC_HEADERS))))
    protocol.stream.handle.assert_called()
    assert protocol.stream.handle.call_args_list == [
        call(
            Request(
                stream_id=1,
                headers=[(b"host", b"hypercorn"), (b"connection", b"close")],
                http_version="1.1",
                method="GET",
                raw_path=b"/?a=b",
            )),
        call(EndBody(stream_id=1)),
    ]
예제 #10
0
async def test_send_app_error(stream: HTTPStream) -> None:
    await stream.handle(
        Request(stream_id=1, http_version="2", headers=[], raw_path=b"/?a=b", method="GET")
    )
    await stream.app_send(None)
    stream.send.assert_called()  # type: ignore
    assert stream.send.call_args_list == [  # type: ignore
        call(
            Response(
                stream_id=1,
                headers=[(b"content-length", b"0"), (b"connection", b"close")],
                status_code=500,
            )
        ),
        call(EndBody(stream_id=1)),
        call(StreamClosed(stream_id=1)),
    ]
    stream.config._log.access.assert_called()  # type: ignore
예제 #11
0
async def test_protocol_handle_closed(protocol: H11Protocol) -> None:
    await protocol.handle(
        RawData(
            data=
            b"GET / HTTP/1.1\r\nHost: hypercorn\r\nConnection: close\r\n\r\n"))
    stream = protocol.stream
    await protocol.handle(Closed())
    stream.handle.assert_called()
    assert stream.handle.call_args_list == [
        call(
            Request(
                stream_id=1,
                headers=[(b"host", b"hypercorn"), (b"connection", b"close")],
                http_version="1.1",
                method="GET",
                raw_path=b"/",
            )),
        call(EndBody(stream_id=1)),
        call(StreamClosed(stream_id=1)),
    ]
예제 #12
0
async def test_invalid_server_name(stream: HTTPStream) -> None:
    stream.config.server_names = ["hypercorn"]
    await stream.handle(
        Request(
            stream_id=1,
            http_version="2",
            headers=[(b"host", b"example.com")],
            raw_path=b"/",
            method="GET",
        ))
    assert stream.send.call_args_list == [  # type: ignore
        call(
            Response(
                stream_id=1,
                headers=[(b"content-length", b"0"), (b"connection", b"close")],
                status_code=404,
            )),
        call(EndBody(stream_id=1)),
    ]
    # This shouldn't error
    await stream.handle(Body(stream_id=1, data=b"Body"))
예제 #13
0
async def test_send_app_error_handshake(stream: WSStream) -> None:
    await stream.handle(
        Request(
            stream_id=1,
            http_version="2",
            headers=[(b"sec-websocket-version", b"13")],
            raw_path=b"/",
            method="GET",
        ))
    await stream.app_send(None)
    stream.send.assert_called()
    assert stream.send.call_args_list == [
        call(
            Response(
                stream_id=1,
                headers=[(b"content-length", b"0"), (b"connection", b"close")],
                status_code=500,
            )),
        call(EndBody(stream_id=1)),
        call(StreamClosed(stream_id=1)),
    ]
    stream.config._log.access.assert_called()
예제 #14
0
async def test_protocol_instant_recycle(
        protocol: H11Protocol, event_loop: asyncio.AbstractEventLoop) -> None:
    # This test task acts as the asgi app, spawned tasks act as the
    # server.
    data = b"GET / HTTP/1.1\r\nHost: hypercorn\r\n\r\n"
    # This test requires a real event as the handling should pause on
    # the instant receipt
    protocol.can_read = EventWrapper()
    task = event_loop.create_task(protocol.handle(RawData(data=data)))
    await asyncio.sleep(0)  # Switch to task
    assert protocol.stream is not None
    assert task.done()
    await protocol.stream_send(
        Response(stream_id=1, status_code=200, headers=[]))
    await protocol.stream_send(EndBody(stream_id=1))
    task = event_loop.create_task(protocol.handle(RawData(data=data)))
    await asyncio.sleep(0)  # Switch to task
    await protocol.stream_send(StreamClosed(stream_id=1))
    await asyncio.sleep(0)  # Switch to task
    # Should have recycled, i.e. a stream should exist
    assert protocol.stream is not None
    assert task.done()