404 with non-/ WSGI, script prefix not removed in core/urlresolvers.py: resolve()
|Reported by:||django@…||Owned by:||nobody|
|Severity:||Normal||Keywords:||404, WSGIScriptAlias, wsgi, resolve, url, prefix|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I've just had a nasty WSGI bug with Django 1.4 while using a non-/ WSGIScriptAlias with apache2. I tracked down the bug and found a cause so here is a patch for review, if you like.
Sorry in advance if this is a known and fixed bug, but then please consider patching 1.4 stable release?
urlpatterns = patterns('', r'^bug/$', 'app.views.Bug')
Django runserver => everything OK
apache2 + WSGIScriptAlias / => everything OK
apache2 + WSGIScriptAlias /test => breaks
Details: request URL '/test/bug/', tried '^bug/$' did not match current URL 'bug/' - silly right? :) obviously this is not reporting the actual URL it was checked against, maybe something to fix to have a more meaningful error message.
A quick debug of WSGI reveals apache is properly giving all the info to Django: SCRIPT_NAME='/test', PATH_INFO='/bug/'.
After a quick search it seems to be a known bug on the interwebs but solutions I've seen were ugly (write the prefix statically in the app).
Diving into Django I found core/urlresolvers.py with:
class RegexURLResolver(LocaleRegexProvider): [...] def resolve(self, path): [...] new_path = path[match.end():] for pattern in self.url_patterns:
With request path '/test/bug/', new_path becomes 'test/bug/', and this obviously does not match against '^bug/$'.
Proposed fix: if present, remove get_script_prefix() from new_path (after applying the same regexp).
new_path = path[match.end():] + # Get script prefix, apply regexp and remove from path if present. + prefix = get_script_prefix() + if prefix: + match = self.regex.search(prefix) + if match: + prefix = prefix[match.end():] + if new_path.startswith(prefix): + new_path = new_path[len(prefix):] for pattern in self.url_patterns:
Now everything works as expected, I hope I did not miss anything.
Let me know if you have any questions and thanks for providing this great framework :)
Change History (6)
Changed 21 months ago by django@…
comment:1 Changed 21 months ago by StalkR
- Cc StalkR added
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
comment:2 Changed 21 months ago by lukeplant
- Resolution set to invalid
- Status changed from new to closed