|
2 | 2 | import os |
3 | 3 | import time |
4 | 4 | from http.cookies import SimpleCookie |
| 5 | +from pathlib import Path |
5 | 6 |
|
6 | 7 | import anyio |
7 | 8 | import pytest |
8 | 9 |
|
9 | 10 | from starlette import status |
10 | 11 | from starlette.background import BackgroundTask |
| 12 | +from starlette.datastructures import Headers |
11 | 13 | from starlette.requests import Request |
12 | 14 | from starlette.responses import ( |
13 | 15 | FileResponse, |
|
17 | 19 | StreamingResponse, |
18 | 20 | ) |
19 | 21 | from starlette.testclient import TestClient |
| 22 | +from starlette.types import Message |
20 | 23 |
|
21 | 24 |
|
22 | 25 | def test_text_response(test_client_factory): |
@@ -244,6 +247,36 @@ async def app(scope, receive, send): |
244 | 247 | assert filled_by_bg_task == "6, 7, 8, 9" |
245 | 248 |
|
246 | 249 |
|
| 250 | +@pytest.mark.anyio |
| 251 | +async def test_file_response_on_head_method(tmpdir: Path): |
| 252 | + path = os.path.join(tmpdir, "xyz") |
| 253 | + content = b"<file content>" * 1000 |
| 254 | + with open(path, "wb") as file: |
| 255 | + file.write(content) |
| 256 | + |
| 257 | + app = FileResponse(path=path, filename="example.png") |
| 258 | + |
| 259 | + async def receive() -> Message: # type: ignore[empty-body] |
| 260 | + ... # pragma: no cover |
| 261 | + |
| 262 | + async def send(message: Message) -> None: |
| 263 | + if message["type"] == "http.response.start": |
| 264 | + assert message["status"] == status.HTTP_200_OK |
| 265 | + headers = Headers(raw=message["headers"]) |
| 266 | + assert headers["content-type"] == "image/png" |
| 267 | + assert "content-length" in headers |
| 268 | + assert "content-disposition" in headers |
| 269 | + assert "last-modified" in headers |
| 270 | + assert "etag" in headers |
| 271 | + elif message["type"] == "http.response.body": |
| 272 | + assert message["body"] == b"" |
| 273 | + assert message["more_body"] is False |
| 274 | + |
| 275 | + # Since the TestClient drops the response body on HEAD requests, we need to test |
| 276 | + # this directly. |
| 277 | + await app({"type": "http", "method": "head"}, receive, send) |
| 278 | + |
| 279 | + |
247 | 280 | def test_file_response_with_directory_raises_error(tmpdir, test_client_factory): |
248 | 281 | app = FileResponse(path=tmpdir, filename="example.png") |
249 | 282 | client = test_client_factory(app) |
|
0 commit comments