#17133 closed Cleanup/optimization (fixed)
get_script_name goofs when there is Apache URL rewriting
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | HTTP handling | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
When running under Apache+mod_wsgi (I'm not sure the mod_wsgi is relevant here), using a WSGIScriptAlias of /foo
, a request for URL /foo/bar//baz
(note double slash) gets transformed by Apache to /foo/bar/baz
and then by Django to /foo//bar/baz
(note where double slashes are now). Furthermore, a callback function for urlpattern "^bar/.*"
will be called on this latter path even though it doesn't match the pattern. That is, request.path will be /foo//bar/baz
, which can be confusing for a callback function that is expecting request.path to match the WSGIScriptAlias plus the urlpattern.
I don't totally understand what Django is doing here, but I believe the problem is in django.core.handlers.base.get_script_name. In that function, to get the script name in this situation Django starts with the environment variable SCRIPT_URL, and strips off a number of characters at the end equal to the length of environment variable PATH_INFO. Because in this case Apache collapses the double slash in /foo/bar//baz
to /foo/bar/baz
, get_script_name strips off one less character than necessary, so that instead of the script name being /foo
it is /foo/
. This may account for the double slash appearing /foo
, as in /foo//bar/baz
.
Attachments (1)
Change History (13)
comment:2 by , 13 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
comment:3 by , 12 years ago
Has patch: | set |
---|---|
Resolution: | needsinfo |
Status: | closed → reopened |
This is definitely a Django bug, given that Apache/mod_wsgi is as it is.
Here are the variables for my case:
SCRIPT_URL = '/mst/milestones//accounts/login//help' PATH_INFO = u'/milestones/accounts/login/help' SCRIPT_NAME = u'/mst/m'
The correct SCRIPT_NAME would be just u'/mst'.
by , 12 years ago
Attachment: | django_script_path.patch added |
---|
Suggested patch (for Django 1.3.1, but should apply on master as well)
comment:4 by , 12 years ago
See e.g. http://trac.edgewall.org/demo-1.1/changeset/10609/branches/0.12-stable/trac/web/main.py for an independent assessment of the same problem.
comment:6 by , 12 years ago
Description: | modified (diff) |
---|
comment:7 by , 12 years ago
Triage Stage: | Unreviewed → Accepted |
---|
Here's an explanation from Graham Dumpleton (a bit old, but seems up-to-date): https://groups.google.com/d/msg/django-users/31oV1WhuAZ4/lpbt_3CCcXYJ
Nitpicking: The import and regexp definition should be on top of the file and a comment with a link to this issue would decrease the WTH level ;)
comment:8 by , 12 years ago
Type: | Uncategorized → Cleanup/optimization |
---|
comment:9 by , 12 years ago
Status: | reopened → new |
---|
comment:12 by , 9 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
While it's clear that something's wrong in your setup, I'm unable to confirm that there's a bug in Django, and determine how we could fix it, sorry.
You might be exceeding the limits of how much
mod_rewrite
magic Django can compensate for; if so, you can work around the problem with theFORCE_SCRIPT_NAME
setting.If we wanted to debug this further, we'd need the values of the relevant environment variables, especially
SCRIPT_URL
,REDIRECT_URL
,PATH_INFO
,SCRIPT_NAME
, as well as the relevant bits of your Apache configuration.