summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2015-10-23 14:53:32 +0200
committerClaude Paroz <claude@2xlibre.net>2015-10-23 22:18:18 +0200
commit10ace52a41fc3458fb7df51d11974b398f0fbde3 (patch)
tree475b4aaca7072f766ab3b30e9806ec009f302bc4
parent494b7986a3e5996d857b085f188a630d1504d9ca (diff)
Fixed #17133 -- Properly handled successive slashes in incoming requests
Thanks gjanee@ucop.edu for the report and Tim Graham for the review.
-rw-r--r--django/core/handlers/wsgi.py6
-rw-r--r--tests/handlers/tests.py11
-rw-r--r--tests/requests/tests.py16
3 files changed, 33 insertions, 0 deletions
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 50766cb7aa..52f5cc5c59 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import cgi
import codecs
import logging
+import re
import sys
from io import BytesIO
from threading import Lock
@@ -21,6 +22,8 @@ logger = logging.getLogger('django.request')
# encode() and decode() expect the charset to be a native string.
ISO_8859_1, UTF_8 = str('iso-8859-1'), str('utf-8')
+_slashes_re = re.compile(br'/+')
+
class LimitedStream(object):
'''
@@ -218,6 +221,9 @@ def get_script_name(environ):
script_url = get_bytes_from_wsgi(environ, 'REDIRECT_URL', '')
if script_url:
+ # mod_wsgi squashes multiple successive slashes in PATH_INFO,
+ # do the same with script_url before manipulating paths (#17133).
+ script_url = _slashes_re.sub(b'/', script_url)
path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '')
script_name = script_url[:-len(path_info)] if path_info else script_url
else:
diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py
index 6097754b59..76cfe5161c 100644
--- a/tests/handlers/tests.py
+++ b/tests/handlers/tests.py
@@ -211,3 +211,14 @@ class ScriptNameTests(SimpleTestCase):
script_name = get_script_name({'SCRIPT_URL': '/foobar/', 'PATH_INFO': '/'})
self.assertEqual(script_name, '/foobar')
+
+ def test_get_script_name_double_slashes(self):
+ """
+ WSGI squashes multiple successive slashes in PATH_INFO, get_script_name
+ should take that into account when forming SCRIPT_NAME (#17133).
+ """
+ script_name = get_script_name({
+ 'SCRIPT_URL': '/mst/milestones//accounts/login//help',
+ 'PATH_INFO': '/milestones/accounts/login/help',
+ })
+ self.assertEqual(script_name, '/mst')
diff --git a/tests/requests/tests.py b/tests/requests/tests.py
index 0b6254d0bb..66fe8c92ec 100644
--- a/tests/requests/tests.py
+++ b/tests/requests/tests.py
@@ -104,6 +104,22 @@ class RequestsTests(SimpleTestCase):
})
self.assertEqual(request.path, '/PREFIX/somepath/')
+ def test_wsgirequest_script_url_double_slashes(self):
+ """
+ WSGI squashes multiple successive slashes in PATH_INFO, WSGIRequest
+ should take that into account when populating request.path and
+ request.META['SCRIPT_NAME'].
+ Refs #17133.
+ """
+ request = WSGIRequest({
+ 'SCRIPT_URL': '/mst/milestones//accounts/login//help',
+ 'PATH_INFO': '/milestones/accounts/login/help',
+ 'REQUEST_METHOD': 'get',
+ 'wsgi.input': BytesIO(b''),
+ })
+ self.assertEqual(request.path, '/mst/milestones/accounts/login/help')
+ self.assertEqual(request.META['SCRIPT_NAME'], '/mst')
+
def test_wsgirequest_with_force_script_name(self):
"""
Ensure that the FORCE_SCRIPT_NAME setting takes precedence over the