sanic/tests/test_http.py

115 lines
2.5 KiB
Python
Raw Permalink Normal View History

2021-07-19 14:52:33 +01:00
import json as stdjson
from collections import namedtuple
2022-06-27 09:19:26 +01:00
from pathlib import Path
from sys import version_info
2021-07-19 14:52:33 +01:00
import pytest
from sanic_testing.reusable import ReusableClient
from sanic import json, text
from sanic.app import Sanic
2022-06-27 09:19:26 +01:00
from tests.client import RawClient
2021-07-19 14:52:33 +01:00
2022-06-27 09:19:26 +01:00
parent_dir = Path(__file__).parent
localhost_dir = parent_dir / "certs/localhost"
2021-07-19 14:52:33 +01:00
2022-06-27 09:19:26 +01:00
PORT = 1234
2021-07-19 14:52:33 +01:00
@pytest.fixture
def test_app(app: Sanic):
app.config.KEEP_ALIVE_TIMEOUT = 1
@app.get("/")
async def base_handler(request):
return text("111122223333444455556666777788889999")
@app.post("/upload", stream=True)
async def upload_handler(request):
data = [part.decode("utf-8") async for part in request.stream]
return json(data)
return app
@pytest.fixture
def runner(test_app: Sanic):
2021-07-19 14:52:33 +01:00
client = ReusableClient(test_app, port=PORT)
client.run()
yield client
client.stop()
@pytest.fixture
def client(runner: ReusableClient):
2021-07-19 14:52:33 +01:00
client = namedtuple("Client", ("raw", "send", "recv"))
raw = RawClient(runner.host, runner.port)
runner._run(raw.connect())
def send(msg):
nonlocal runner
nonlocal raw
runner._run(raw.send(msg))
def recv(**kwargs):
nonlocal runner
nonlocal raw
method = raw.recv_until if "until" in kwargs else raw.recv
return runner._run(method(**kwargs))
yield client(raw, send, recv)
runner._run(raw.close())
def test_full_message(client):
client.send(
"""
GET / HTTP/1.1
host: localhost:7777
"""
)
response = client.recv()
# AltSvcCheck touchup removes the Alt-Svc header from the
# response in the Python 3.9+ in this case
assert len(response) == (151 if version_info < (3, 9) else 140)
2021-07-19 14:52:33 +01:00
assert b"200 OK" in response
def test_transfer_chunked(client):
client.send(
"""
POST /upload HTTP/1.1
transfer-encoding: chunked
"""
)
client.send(b"3\r\nfoo\r\n")
client.send(b"3\r\nbar\r\n")
client.send(b"0\r\n\r\n")
response = client.recv()
_, body = response.rsplit(b"\r\n\r\n", 1)
data = stdjson.loads(body)
assert data == ["foo", "bar"]
def test_url_encoding(client):
client.send(
"""
GET /invalid\xA0url HTTP/1.1
"""
)
response = client.recv()
headers, body = response.rsplit(b"\r\n\r\n", 1)
assert b"400 Bad Request" in headers
assert b"URL may only contain US-ASCII characters." in body