from typing import TYPE_CHECKING, Callable, List, Optional, Tuple, Union
+from urllib.parse import unquote
import httpcore
import sniffio
"method": method.decode(),
"headers": headers,
"scheme": scheme.decode("ascii"),
- "path": path.decode("ascii"),
+ "path": unquote(path.decode("ascii")),
"query_string": query,
"server": (host.decode("ascii"), port),
"client": self.client,
+import json
+
import pytest
import httpx
await send({"type": "http.response.body", "body": output})
+async def echo_path(scope, receive, send):
+ status = 200
+ output = json.dumps({"path": scope["path"]}).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 echo_body(scope, receive, send):
status = 200
headers = [(b"content-type", "text/plain")]
assert response.text == "Hello, World!"
+@pytest.mark.usefixtures("async_environment")
+async def test_asgi_urlencoded_path():
+ async with httpx.AsyncClient(app=echo_path) as client:
+ url = httpx.URL("http://www.example.org/").copy_with(path="/user@example.org")
+ response = await client.get(url)
+
+ assert response.status_code == 200
+ assert response.json() == {"path": "/user@example.org"}
+
+
@pytest.mark.usefixtures("async_environment")
async def test_asgi_upload():
async with httpx.AsyncClient(app=echo_body) as client: