Opened 12 years ago
Closed 12 years ago
#19046 closed Bug (needsinfo)
staticfiles not finding the files on Windows
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | contrib.staticfiles | Version: | 1.4 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I'm using Django 1.4 on Windows XP and when a file is requested from STATIC_ROOT I get the following error:
Traceback (most recent call last): File "C:\Python27\lib\wsgiref\handlers.py", line 85, in run self.result = application(self.environ, self.start_response) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\handlers.py", line 68, in __call__ return super(StaticFilesHandler, self).__call__(environ, start_response) File "C:\Python27\lib\site-packages\django\core\handlers\wsgi.py", line 241, in __call__ response = self.get_response(request) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\handlers.py", line 58, in get_response return self.serve(request) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\handlers.py", line 51, in serve return serve(request, self.file_path(request.path), insecure=True) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\views.py", line 35, in serve absolute_path = finders.find(normalized_path) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\finders.py", line 238, in find result = finder.find(path, all=all) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\finders.py", line 78, in find matched_path = self.find_location(root, path, prefix) File "C:\Python27\lib\site-packages\django\contrib\staticfiles\finders.py", line 95, in find_location path = safe_join(root, path) File "C:\Python27\lib\site-packages\django\utils\_os.py", line 52, in safe_join 'path component (%s)' % (final_path, base_path)) ValueError: The joined path (C:\images\common\fnurse.jpg) is located outside of the base path component (C:\DJANGO\webtech-proto-work\static) [01/Oct/2012 09:34:06] "GET /static/images/common/fnurse.jpg HTTP/1.1" 500 59
I have traced the cause of the error to line 37 in staticfiles/views.py :
normalized_path = posixpath.normpath(unquote(path)).lstrip('/')
I have replaced the hardcoded '/' to os.sep and after that static files have been served on Windows. Please check if this change is correct and if it correct than please integrate it.
Change History (3)
comment:1 by , 12 years ago
Severity: | Normal → Release blocker |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Bug |
comment:2 by , 12 years ago
Easy pickings: | unset |
---|---|
Severity: | Release blocker → Normal |
comment:3 by , 12 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
posixpath is the module that is used on POSIX systems when import os.path. It uses the hardcoded forward slash and a couple of other things different to the ntpath module that does the same for Windows systems. In other words os.path just a facade for the platform specific tools. The different modules are documented on http://docs.python.org/2/library/os.path.html
The lstrip('/') happens there since the path passed to the serve view may be formatted as http://localhost:8000/static///someother/file.ext
making path having a value of //someother/file.ext
. The posix.normpath happens there to remove redundancies in the path (e.g. path/to/../some//file.ext
is converted to path/some/file.ext
). The finder api expects that kind of cleaned up name to make sure it does the right thing later on.
As I'm not able to reproduce the issue with the current code, I'm closing as needsinfo. A testcase that demostrates the issue would be appreciated, for example.
It wasn't easy but I eventually managed to reproduce this problem.
Here's what I did:
STATIC_ROOT = './static'
(no trailing slash -- otherwise the bug doesn't happen),STATICFILES_DIRS = ('./static_src/',)
django/conf/__init__.py
to cancel the effects of fbfaa35fb0a2a1206221e00c56cf6136cf93b6f1 -- otherwise Django refuses to startstatic_src/yay.txt
http://localhost:8000/static/yay.txt
Since fbfaa35fb0a2a1206221e00c56cf6136cf93b6f1, Django requires
STATIC_URL
to end with a slash, so this problem cannot occur in Django 1.5. For this reason, I'm going to downgrade the severity.However, I still feel there's something wrong with this line:
As far as I can tell:
posixpath
module from Python's standard library is used to perform path normalization with forward slashes, which seems suitable for URLs;.lstrip('/')
is intended to strip the leading slash from the URL, in caseSTATIC_URL
setting doesn't end in a slash.I see two problems:
serve()
function receivespath = '\yay.txt'
— the backslash has absolutely no reason for being here; everything's happening in "URL-space", not in "file-space" until this point;.lstrip('/')
isn't necessary any longer since Django >= 1.5 requiresSTATIC_URL
to end in a slash.