async def test_handle_request_http_2(stream: HTTPStream) -> None: await stream.handle( Request(stream_id=1, http_version="2", headers=[], raw_path=b"/?a=b", method="GET")) stream.context.spawn_app.assert_called() # type: ignore scope = stream.context.spawn_app.call_args[0][2] # type: ignore assert scope == { "type": "http", "http_version": "2", "asgi": { "spec_version": "2.1" }, "method": "GET", "scheme": "http", "path": "/", "raw_path": b"/", "query_string": b"a=b", "root_path": stream.config.root_path, "headers": [], "client": None, "server": None, "extensions": { "http.response.push": {} }, }
async def test_handle_request(stream: WSStream) -> None: await stream.handle( Request( stream_id=1, http_version="2", headers=[(b"sec-websocket-version", b"13")], raw_path=b"/?a=b", method="GET", )) stream.context.spawn_app.assert_called() # type: ignore scope = stream.context.spawn_app.call_args[0][2] # type: ignore assert scope == { "type": "websocket", "asgi": { "spec_version": "2.1" }, "scheme": "ws", "http_version": "2", "path": "/", "raw_path": b"/", "query_string": b"a=b", "root_path": "", "headers": [(b"sec-websocket-version", b"13")], "client": None, "server": None, "subprotocols": [], "extensions": { "websocket.http.response": {} }, }
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
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
async def test_handle_request_http_1(stream: HTTPStream, http_version: str) -> None: await stream.handle( Request(stream_id=1, http_version=http_version, headers=[], raw_path=b"/?a=b", method="GET")) stream.spawn_app.assert_called() scope = stream.spawn_app.call_args[0][0] assert scope == { "type": "http", "http_version": http_version, "asgi": { "spec_version": "2.1" }, "method": "GET", "scheme": "http", "path": "/", "raw_path": b"/", "query_string": b"a=b", "root_path": stream.config.root_path, "headers": [], "client": None, "server": None, }
async def test_send_connection(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(WebsocketAcceptEvent, {"type": "websocket.accept"})) await stream.app_send( cast(WebsocketSendEvent, { "type": "websocket.send", "text": "hello" })) await stream.app_send( cast(WebsocketCloseEvent, {"type": "websocket.close"})) stream.send.assert_called() # type: ignore assert stream.send.call_args_list == [ # type: ignore call(Response(stream_id=1, headers=[], status_code=200)), call(Data(stream_id=1, data=b"\x81\x05hello")), call(Data(stream_id=1, data=b"\x88\x02\x03\xe8")), call(EndData(stream_id=1)), ]
async def test_send_accept_with_additional_headers(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( WebsocketAcceptEvent, { "type": "websocket.accept", "headers": [(b"additional", b"header")] }, )) assert stream.state == ASGIWebsocketState.CONNECTED stream.send.assert_called() # type: ignore assert stream.send.call_args_list == [ # type: ignore call( Response(stream_id=1, headers=[(b"additional", b"header")], status_code=200)) ]
async def test_send_accept(stream: WSStream) -> None: await stream.handle( Request( stream_id=1, http_version="2.0", headers=[(b"sec-websocket-version", b"13")], raw_path=b"/", method="GET", ) ) await stream.app_send({"type": "websocket.accept"}) assert stream.state == ASGIWebsocketState.CONNECTED stream.send.assert_called() assert stream.send.call_args_list == [call(Response(stream_id=1, headers=[], status_code=200))]
async def test_send_push(stream: HTTPStream, http_scope: HTTPScope) -> None: stream.scope = http_scope stream.stream_id = 1 await stream.app_send({"type": "http.response.push", "path": "/push", "headers": []}) assert stream.send.call_args_list == [ # type: ignore call( Request( stream_id=1, headers=[(b":scheme", b"https")], http_version="2", method="GET", raw_path=b"/push", ) ) ]
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)), ]
async def test_handle_connection(stream: WSStream) -> None: await stream.handle( Request( stream_id=1, http_version="2.0", headers=[(b"sec-websocket-version", b"13")], raw_path=b"/?a=b", method="GET", ) ) await stream.app_send({"type": "websocket.accept"}) stream.app_put = CoroutineMock() await stream.handle(Data(stream_id=1, data=b"\x81\x85&`\x13\x0eN\x05\x7fbI")) stream.app_put.assert_called() assert stream.app_put.call_args_list == [ call({"type": "websocket.receive", "bytes": None, "text": "hello"}) ]
async def test_send_app_error_connected(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({"type": "websocket.accept"}) await stream.app_send(None) stream.send.assert_called() assert stream.send.call_args_list == [ call(Response(stream_id=1, headers=[], status_code=200)), call(Data(stream_id=1, data=b"\x88\x02\x03\xe8")), call(StreamClosed(stream_id=1)), ] stream.config._log.access.assert_called()
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
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)), ]
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"))
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()
async def test_pings(stream: WSStream, event_loop: asyncio.AbstractEventLoop) -> None: stream.config.websocket_ping_interval = 0.1 await stream.handle( Request( stream_id=1, http_version="2", headers=[(b"sec-websocket-version", b"13")], raw_path=b"/?a=b", method="GET", ) ) async with TaskGroup(event_loop) as task_group: stream.context = Context(task_group) await stream.app_send({"type": "websocket.accept"}) stream.app_put = AsyncMock() await asyncio.sleep(0.15) assert stream.send.call_args_list == [ call(Response(stream_id=1, headers=[], status_code=200)), call(Data(stream_id=1, data=b"\x89\x00")), call(Data(stream_id=1, data=b"\x89\x00")), ] await stream.handle(StreamClosed(stream_id=1))
async def test_send_push(stream: HTTPStream) -> None: stream.scope = { "scheme": "https", "headers": [(b"host", b"hypercorn")], "http_version": "2" } stream.stream_id = 1 await stream.app_send({ "type": "http.response.push", "path": "/push", "headers": [] }) assert stream.send.call_args_list == [ call( Request( stream_id=1, headers=[(b":scheme", b"https"), (b":authority", b"hypercorn")], http_version="2", method="GET", raw_path=b"/push", )) ]