1e24fd5354
#1 [medium] FileResponse with stat_result=None re-stats at send-time and raises a RuntimeError (-> 500 + stacktrace, escaping get_media's try/except) if the file was swept between the early exists() check and the send. The old streaming code caught FileNotFoundError on getsize -> 404. Now prepare_file_response takes ONE authoritative os.stat (in try/except FileNotFoundError -> 404) after the temp_* touch and passes it as FileResponse(stat_result=...): restores the 404 semantics, collapses the double stat into one, and makes the ETag reflect the observed mtime. The remaining narrow deleted-between-our-stat-and-open window pre-existed. #2/#3 [doc] Corrected the Content-Disposition comment (FileResponse emits filename="x" for ASCII, filename*=UTF-8''x only for non-ASCII, via setdefault — a manual header would override, not double) and the ETag-stability comment (stable within a 300s window; a longer view costs at most one safe 200 If-Range restart per interval). #4 [simplification] Removed the now-dead StreamingResponse import and corrected get_media's return annotation to -> Response (nothing returns StreamingResponse after the FileResponse migration). #5 [test] Added a test for the middleware's non-http (lifespan/websocket) branch — it only runs in a real deploy, never through TestClient — asserting it delegates to the inner app and logs nothing. 214 passed (195 baseline + 19). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>