Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StaticFiles causes Internal Server Error when user accesses existing files as directory #1123

Closed
2 tasks done
xKerman opened this issue Jan 11, 2021 · 0 comments · Fixed by #1220
Closed
2 tasks done
Labels
staticfiles Static file serving

Comments

@xKerman
Copy link

xKerman commented Jan 11, 2021

Checklist

  • The bug is reproducible against the latest release and/or master.
  • There are no similar issues or pull requests to fix it yet.

Describe the bug

StaticFiles causes Internal Server Error when user accesses existing files as directory (e.g. /static/somefile.txt/foobar)

To reproduce

  1. create virtual env and activate it with python -m venv venv && source venv/bin/activate
  2. install dependencies with pip install starlette uvicorn aiofiles
  3. setup application as follows:

directory structure:

.
├── poc.py
├── static
│   └── sample.txt
└── venv

poc.py

# code from https://www.starlette.io/staticfiles/
from starlette.applications import Starlette
from starlette.routing import Mount
from starlette.staticfiles import StaticFiles


routes = [
    Mount("/static", app=StaticFiles(directory="static"), name="static"),
]

app = Starlette(routes=routes)
  1. run application with uvicorn poc:app
  2. access http://127.0.0.1:8000/static/sample.txt/foo

Expected behavior

StaticFiles returns "404 Not Found" HTTP response (as Apache HTTP Server and Nginx does).

Actual behavior

StaticFiles returns "500 Internal Server Error" HTTP response.

Debugging material

console log with tracebacks:

INFO:     Started server process [13052]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:64288 - "GET /static/sample.txt/foo HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 394, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/routing.py", line 582, in __call__
    await route.handle(scope, receive, send)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/routing.py", line 392, in handle
    await self.app(scope, receive, send)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/staticfiles.py", line 97, in __call__
    response = await self.get_response(path, scope)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/staticfiles.py", line 114, in get_response
    full_path, stat_result = await self.lookup_path(path)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/starlette/staticfiles.py", line 154, in lookup_path
    stat_result = await aio_stat(full_path)
  File "/Users/xkhorasan/programs/test_starlette/venv/lib/python3.9/site-packages/aiofiles/os.py", line 13, in run
    return await loop.run_in_executor(executor, pfunc)
  File "/usr/local/Cellar/python@3.9/3.9.1_2/Frameworks/Python.framework/Versions/3.9/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
NotADirectoryError: [Errno 20] Not a directory: '/Users/xkhorasan/programs/test_starlette/static/sample.txt/foo'

Environment

  • OS: macOS
  • Python version: 3.9.1
  • Starlette version: 0.14.1

Additional context

Apache HTTP Server and Nginx treat this case (access existing file as directory) as "404 Not Found".
Samples:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
staticfiles Static file serving
Projects
None yet
2 participants