]> git.ipfire.org Git - thirdparty/starlette.git/commitdiff
Send 404 instead of 500 when filename requested is too long on `StaticFiles` (#2583)
authorJeremy Epstein <jazepstein@gmail.com>
Sat, 1 Jun 2024 13:07:03 +0000 (23:07 +1000)
committerGitHub <noreply@github.com>
Sat, 1 Jun 2024 13:07:03 +0000 (13:07 +0000)
* Make "Filename too long" return 404 not 500

* Simplify code source

* Correct comment

---------

Co-authored-by: Jeremy Epstein <jeremy.epstein@seertechsolutions.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
starlette/staticfiles.py
tests/test_staticfiles.py

index 5d0856ccc54d4640ddbbc12fbbc754436567bcff..afb09b56b24e4c1dbed401d04842e1adc052f06d 100644 (file)
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import errno
 import importlib.util
 import os
 import stat
@@ -124,8 +125,12 @@ class StaticFiles:
             )
         except PermissionError:
             raise HTTPException(status_code=401)
-        except OSError:
-            raise
+        except OSError as exc:
+            # Filename is too long, so it can't be a valid static file.
+            if exc.errno == errno.ENAMETOOLONG:
+                raise HTTPException(status_code=404)
+
+            raise exc
 
         if stat_result and stat.S_ISREG(stat_result.st_mode):
             # We have a static file to serve.
index d20bb7ef7a0408d9d726b4d244ef2d7625df35ff..085301302e4033f761cd60568258115d419dea62 100644 (file)
@@ -469,6 +469,19 @@ def test_staticfiles_access_file_as_dir_returns_404(
     assert response.text == "Not Found"
 
 
+def test_staticfiles_filename_too_long(
+    tmpdir: Path, test_client_factory: TestClientFactory
+) -> None:
+    routes = [Mount("/", app=StaticFiles(directory=tmpdir), name="static")]
+    app = Starlette(routes=routes)
+    client = test_client_factory(app)
+
+    path_max_size = os.pathconf("/", "PC_PATH_MAX")
+    response = client.get(f"/{'a' * path_max_size}.txt")
+    assert response.status_code == 404
+    assert response.text == "Not Found"
+
+
 def test_staticfiles_unhandled_os_error_returns_500(
     tmpdir: Path,
     test_client_factory: TestClientFactory,