Skip to content

Commit

Permalink
StaticFiles: Fix cache validation bug for deleted files in html mode (#…
Browse files Browse the repository at this point in the history
…1023)

* StaticFiles: Fix cache validation bug for deleted files in html mode

Previously StaticFiles would return 304 for a deleted file if its
Last-Modified date was the same as that of 404.html

* Use black formatter

Co-authored-by: Jamie Hewland <jhewland@gmail.com>
  • Loading branch information
jvstme and JayH5 committed Feb 5, 2021
1 parent 3274594 commit 0ac60bb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
7 changes: 5 additions & 2 deletions starlette/staticfiles.py
Expand Up @@ -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)
Expand Down
37 changes: 37 additions & 0 deletions tests/test_staticfiles.py
Expand Up @@ -243,3 +243,40 @@ def test_staticfiles_html(tmpdir):
response = client.get("/missing")
assert response.status_code == 404
assert response.text == "<h1>Custom not found page</h1>"


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("<p>404 file</p>")
path_some = os.path.join(tmpdir, "some.html")
with open(path_some, "w") as file:
file.write("<p>some file</p>")

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 == "<p>some file</p>"

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 == "<p>404 file</p>"

0 comments on commit 0ac60bb

Please sign in to comment.