diff options
| author | Aymeric Augustin <aymeric.augustin@m4x.org> | 2012-12-17 10:49:26 +0100 |
|---|---|---|
| committer | Aymeric Augustin <aymeric.augustin@m4x.org> | 2012-12-22 13:32:39 +0100 |
| commit | 1e4a27d08790c96f657d2e960c8142d1ca69aede (patch) | |
| tree | 0f628babc0ea651867a223fbf7d9281bb2ce218b /django/core | |
| parent | d9a0b6ab36b6beb4251acf1de1fdf255e1223e02 (diff) | |
Fixed #19468 -- Decoded request.path correctly on Python 3.
Thanks aliva for the report and claudep for the feedback.
Diffstat (limited to 'django/core')
| -rw-r--r-- | django/core/handlers/base.py | 43 | ||||
| -rw-r--r-- | django/core/handlers/wsgi.py | 2 |
2 files changed, 29 insertions, 16 deletions
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index 0caf6b29fa..023947585e 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -5,10 +5,14 @@ import sys import types from django import http +from django.conf import settings +from django.core import exceptions +from django.core import urlresolvers from django.core import signals from django.utils.encoding import force_text from django.utils.importlib import import_module from django.utils import six +from django.views import debug logger = logging.getLogger('django.request') @@ -32,8 +36,6 @@ class BaseHandler(object): Must be called after the environment is fixed (see __call__ in subclasses). """ - from django.conf import settings - from django.core import exceptions self._view_middleware = [] self._template_response_middleware = [] self._response_middleware = [] @@ -75,9 +77,6 @@ class BaseHandler(object): def get_response(self, request): "Returns an HttpResponse object for the given HttpRequest" - from django.core import exceptions, urlresolvers - from django.conf import settings - try: # Setup default url resolver for this thread, this code is outside # the try/except so we don't get a spurious "unbound local @@ -147,7 +146,6 @@ class BaseHandler(object): 'request': request }) if settings.DEBUG: - from django.views import debug response = debug.technical_404_response(request, e) else: try: @@ -204,8 +202,6 @@ class BaseHandler(object): caused by anything, so assuming something like the database is always available would be an error. """ - from django.conf import settings - if settings.DEBUG_PROPAGATE_EXCEPTIONS: raise @@ -218,7 +214,6 @@ class BaseHandler(object): ) if settings.DEBUG: - from django.views import debug return debug.technical_500_response(request, *exc_info) # If Http500 handler is not installed, re-raise last exception @@ -238,6 +233,20 @@ class BaseHandler(object): response = func(request, response) return response + +def get_path_info(environ): + """ + Returns the HTTP request's PATH_INFO as a unicode string. + """ + path_info = environ.get('PATH_INFO', str('/')) + # Under Python 3, strings in environ are decoded with ISO-8859-1; + # re-encode to recover the original bytestring provided by the webserver. + if six.PY3: + path_info = path_info.encode('iso-8859-1') + # It'd be better to implement URI-to-IRI decoding, see #19508. + return path_info.decode('utf-8') + + def get_script_name(environ): """ Returns the equivalent of the HTTP request's SCRIPT_NAME environment @@ -246,7 +255,6 @@ def get_script_name(environ): from the client's perspective), unless the FORCE_SCRIPT_NAME setting is set (to anything). """ - from django.conf import settings if settings.FORCE_SCRIPT_NAME is not None: return force_text(settings.FORCE_SCRIPT_NAME) @@ -255,9 +263,14 @@ def get_script_name(environ): # rewrites. Unfortunately not every Web server (lighttpd!) passes this # information through all the time, so FORCE_SCRIPT_NAME, above, is still # needed. - script_url = environ.get('SCRIPT_URL', '') - if not script_url: - script_url = environ.get('REDIRECT_URL', '') + script_url = environ.get('SCRIPT_URL', environ.get('REDIRECT_URL', str(''))) if script_url: - return force_text(script_url[:-len(environ.get('PATH_INFO', ''))]) - return force_text(environ.get('SCRIPT_NAME', '')) + script_name = script_url[:-len(environ.get('PATH_INFO', str('')))] + else: + script_name = environ.get('SCRIPT_NAME', str('')) + # Under Python 3, strings in environ are decoded with ISO-8859-1; + # re-encode to recover the original bytestring provided by the webserver. + if six.PY3: + script_name = script_name.encode('iso-8859-1') + # It'd be better to implement URI-to-IRI decoding, see #19508. + return script_name.decode('utf-8') diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 4c0710549a..426679ca7b 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -128,7 +128,7 @@ class LimitedStream(object): class WSGIRequest(http.HttpRequest): def __init__(self, environ): script_name = base.get_script_name(environ) - path_info = force_text(environ.get('PATH_INFO', '/')) + path_info = base.get_path_info(environ) if not path_info or path_info == script_name: # Sometimes PATH_INFO exists, but is empty (e.g. accessing # the SCRIPT_NAME URL without a trailing slash). We really need to |
