From: Tom Christie Date: Thu, 8 Oct 2020 11:04:10 +0000 (+0100) Subject: Force lowercase ASGI headers (#1351) X-Git-Tag: 0.16.1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0123bca3354fffcad08f7bbf7662982969b1ac63;p=thirdparty%2Fhttpx.git Force lowercase ASGI headers (#1351) Co-authored-by: Florimond Manca --- diff --git a/httpx/_transports/asgi.py b/httpx/_transports/asgi.py index b47f68b5..5d4fac22 100644 --- a/httpx/_transports/asgi.py +++ b/httpx/_transports/asgi.py @@ -87,7 +87,7 @@ class ASGITransport(httpcore.AsyncHTTPTransport): "asgi": {"version": "3.0"}, "http_version": "1.1", "method": method.decode(), - "headers": headers, + "headers": [(k.lower(), v) for (k, v) in headers], "scheme": scheme.decode("ascii"), "path": unquote(path.decode("ascii")), "query_string": query, diff --git a/tests/test_asgi.py b/tests/test_asgi.py index 4aac735a..a8261e93 100644 --- a/tests/test_asgi.py +++ b/tests/test_asgi.py @@ -36,6 +36,17 @@ async def echo_body(scope, receive, send): await send({"type": "http.response.body", "body": body, "more_body": more_body}) +async def echo_headers(scope, receive, send): + status = 200 + output = json.dumps( + {"headers": [[k.decode(), v.decode()] for k, v in scope["headers"]]} + ).encode("utf-8") + headers = [(b"content-type", "text/plain"), (b"content-length", str(len(output)))] + + await send({"type": "http.response.start", "status": status, "headers": headers}) + await send({"type": "http.response.body", "body": output}) + + async def raise_exc(scope, receive, send): raise RuntimeError() @@ -78,6 +89,23 @@ async def test_asgi_upload(): assert response.text == "example" +@pytest.mark.usefixtures("async_environment") +async def test_asgi_headers(): + async with httpx.AsyncClient(app=echo_headers) as client: + response = await client.get("http://www.example.org/") + + assert response.status_code == 200 + assert response.json() == { + "headers": [ + ["host", "www.example.org"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate, br"], + ["connection", "keep-alive"], + ["user-agent", f"python-httpx/{httpx.__version__}"], + ] + } + + @pytest.mark.usefixtures("async_environment") async def test_asgi_exc(): async with httpx.AsyncClient(app=raise_exc) as client: