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

SharedDataMiddleware fails with IsADirectory #1599

Closed
ThiefMaster opened this issue Jul 4, 2019 · 7 comments · Fixed by #1647
Closed

SharedDataMiddleware fails with IsADirectory #1599

ThiefMaster opened this issue Jul 4, 2019 · 7 comments · Fixed by #1647
Milestone

Comments

@ThiefMaster
Copy link
Member

@ThiefMaster ThiefMaster commented Jul 4, 2019

Minimal example:

from flask import Flask
from werkzeug.middleware.shared_data import SharedDataMiddleware

app = Flask(__name__)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {'/': ('flask', 'json')})

This only seems to happen when using / with the tuple syntax to reference a package. When using another mapping like /test/ it works fine.

Traceback (most recent call last):
  File "/home/adrian/dev/flask-react-example/.venv/lib/python3.7/site-packages/flask/app.py", line 2328, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/adrian/dev/flask-react-example/.venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py", line 231, in __call__
    f, mtime, file_size = file_loader()
  File "/home/adrian/dev/flask-react-example/.venv/lib/python3.7/site-packages/werkzeug/middleware/shared_data.py", line 132, in <lambda>
    open(filename, "rb"),
IsADirectoryError: [Errno 21] Is a directory: '/home/adrian/dev/flask-react-example/.venv/lib/python3.7/site-packages/flask/json/'
@davidism

This comment has been minimized.

@davidism
Copy link
Member

@davidism davidism commented Sep 18, 2019

This seems to be expected, and it happens even with a /test/ prefix. You need to point to a file to serve, not the directory itself. For example, for {"/test": ("werkzeug.debug", "shared")}, /test/ fails because it's the directory, not a file, but /test/console.png succeeds.

This should probably return a 404 though. Also, we should be depending on importlib_resources, not pkg_resources, for this.

@ThiefMaster
Copy link
Member Author

@ThiefMaster ThiefMaster commented Sep 18, 2019

That would mean that packages and normal filesystem paths have different locations - the latter do support pointing to a directory and I think it makes perfect sense that you point this middleware to a directory and not a file...

@ThiefMaster ThiefMaster changed the title SharedDateMiddleware fails with IsADirectory SharedDataMiddleware fails with IsADirectory Sep 18, 2019
@davidism
Copy link
Member

@davidism davidism commented Sep 19, 2019

You do point at a directory, but it only serves files. If you go to the top level, you don't get a directory listing, you need to go to an actual file within the directory.

What do you expect to get when visiting /or /test/ in your example?

@ThiefMaster
Copy link
Member Author

@ThiefMaster ThiefMaster commented Sep 19, 2019

OK, after testing it again now I remember the exact issue:

Let's take this example:

from flask import Flask
from werkzeug.middleware.shared_data import SharedDataMiddleware

app = Flask(__name__)
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
    '/': ('flask', 'json'),
    '/test/': ('flask', 'json'),
    '/fs/': '/var/empty/',
})
  • http://localhost/: IsADirectoryError
  • http://localhost/test/: IsADirectoryError
  • http://localhost/fs/: 404 ✔️

IMO the first two options should 404 as well to be consistent and not cause an actual exception simply due to a client requesting that URL. 403 would probably be even more suitable for all cases since AFAIK that's what real webserver usually do when you attempt to access a directory that has no directory listing enabled.

@davidism
Copy link
Member

@davidism davidism commented Sep 19, 2019

Definitely agree they should raise 403/4 instead of 500, thanks for clarifying.

@davidism
Copy link
Member

@davidism davidism commented Sep 20, 2019

Due to the way the middleware works, we can't return 403 as unhandled paths are intended to pass through to the app, which is what's actually raising the 404. Would be too big a rewrite at this point to support 403.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants