diff --git a/starlette/staticfiles.py b/starlette/staticfiles.py index 8822efd10..225e45745 100644 --- a/starlette/staticfiles.py +++ b/starlette/staticfiles.py @@ -134,8 +134,11 @@ async def get_response(self, path: str, scope: Scope) -> Response: # Check for '404.html' if we're in HTML mode. full_path, stat_result = await self.lookup_path("404.html") if stat_result is not None and stat.S_ISREG(stat_result.st_mode): - return self.file_response( - full_path, stat_result, scope, status_code=404 + return FileResponse( + full_path, + stat_result=stat_result, + method=scope["method"], + status_code=404, ) return PlainTextResponse("Not Found", status_code=404) diff --git a/tests/test_staticfiles.py b/tests/test_staticfiles.py index da1c250a8..6b325071f 100644 --- a/tests/test_staticfiles.py +++ b/tests/test_staticfiles.py @@ -243,3 +243,40 @@ def test_staticfiles_html(tmpdir): response = client.get("/missing") assert response.status_code == 404 assert response.text == "

Custom not found page

" + + +def test_staticfiles_cache_invalidation_for_deleted_file_html_mode(tmpdir): + path_404 = os.path.join(tmpdir, "404.html") + with open(path_404, "w") as file: + file.write("

404 file

") + path_some = os.path.join(tmpdir, "some.html") + with open(path_some, "w") as file: + file.write("

some file

") + + common_modified_time = time.mktime( + time.strptime("2013-10-10 23:40:00", "%Y-%m-%d %H:%M:%S") + ) + os.utime(path_404, (common_modified_time, common_modified_time)) + os.utime(path_some, (common_modified_time, common_modified_time)) + + app = StaticFiles(directory=tmpdir, html=True) + client = TestClient(app) + + resp_exists = client.get("/some.html") + assert resp_exists.status_code == 200 + assert resp_exists.text == "

some file

" + + resp_cached = client.get( + "/some.html", + headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, + ) + assert resp_cached.status_code == 304 + + os.remove(path_some) + + resp_deleted = client.get( + "/some.html", + headers={"If-Modified-Since": resp_exists.headers["last-modified"]}, + ) + assert resp_deleted.status_code == 404 + assert resp_deleted.text == "

404 file

"