--
Ticket URL: <https://code.djangoproject.com/ticket/17133>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_docs: => 0
* needs_tests: => 0
* needs_better_patch: => 0
Comment:
Sorry, the wiki formatting screwed the description up, attempt number 2:
{{{
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.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:1>
* status: new => closed
* resolution: => needsinfo
Comment:
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 the
`FORCE_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.
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:2>
* status: closed => reopened
* has_patch: 0 => 1
* resolution: needsinfo =>
Comment:
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'.
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:3>
Comment (by mwilck):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:4>
Comment (by anonymous):
Replying to [comment:3 mwilck]:
Sorry I messed up the formatting, and it's important here.
{{{
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'.
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:5>
Old description:
> 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.
New description:
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`.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:6>
* needs_docs: => 0
* needs_better_patch: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted
Comment:
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 ;)
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:7>
* type: Uncategorized => Cleanup/optimization
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:8>
* needs_tests: 0 => 1
Comment:
Is there any way to add a test?
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:10>
* version: 1.3 => master
* needs_tests: 1 => 0
Comment:
PR [https://github.com/django/django/pull/5468 #5468]
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:11>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:12>
* status: new => closed
* resolution: => fixed
Comment:
In [changeset:"10ace52a41fc3458fb7df51d11974b398f0fbde3" 10ace52a]:
{{{
#!CommitTicketReference repository=""
revision="10ace52a41fc3458fb7df51d11974b398f0fbde3"
Fixed #17133 -- Properly handled successive slashes in incoming requests
Thanks gja...@ucop.edu for the report and Tim Graham for the review.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:13>
Comment (by Claude Paroz <claude@…>):
In [changeset:"ea2f48ce8bd865874108af79766cdef2d197e540" ea2f48c]:
{{{
#!CommitTicketReference repository=""
revision="ea2f48ce8bd865874108af79766cdef2d197e540"
Refs #17133 -- Optimized script_url handling in get_script_name
10ace52a added some regex processing for each request with SCRIPT_URL set.
In a speed critical section, conditionally apply of the regex will save
some
resources.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/17133#comment:14>