diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/handlers/base.py | 17 | ||||
| -rw-r--r-- | django/http/__init__.py | 17 | ||||
| -rw-r--r-- | django/test/testcases.py | 8 |
3 files changed, 35 insertions, 7 deletions
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index ca48b301d4..768fc14b00 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -50,6 +50,10 @@ class BaseHandler(object): def get_response(self, request): "Returns an HttpResponse object for the given HttpRequest" + response = self._real_get_response(request) + return fix_location_header(request, response) + + def _real_get_response(self, request): from django.core import exceptions, urlresolvers from django.core.mail import mail_admins from django.conf import settings @@ -129,3 +133,16 @@ class BaseHandler(object): "Helper function to return the traceback as a string" import traceback return '\n'.join(traceback.format_exception(*(exc_info or sys.exc_info()))) + +def fix_location_header(request, response): + """ + Ensure that we always use an absolute URI in any location header in the + response. This is required by RFC 2616, section 14.30. + + Code constructing response objects is free to insert relative paths and + this function converts them to absolute paths. + """ + if 'Location' in response.headers and http.get_host(request): + response['Location'] = request.build_absolute_uri(response['Location']) + return response + diff --git a/django/http/__init__.py b/django/http/__init__.py index 20818f138b..74764690a3 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -2,6 +2,7 @@ import os from Cookie import SimpleCookie from pprint import pformat from urllib import urlencode +from urlparse import urljoin from django.utils.datastructures import MultiValueDict, FileDict from django.utils.encoding import smart_str, iri_to_uri, force_unicode @@ -42,10 +43,24 @@ class HttpRequest(object): return key in self.GET or key in self.POST __contains__ = has_key - + def get_full_path(self): return '' + def build_absolute_uri(self, location=None): + """ + Builds an absolute URI from the location and the variables available in + this request. If no location is specified, the absolute URI is built on + ``request.get_full_path()``. + """ + if not location: + location = request.get_full_path() + if not ':' in location: + current_uri = '%s://%s%s' % (self.is_secure() and 'https' or 'http', + get_host(self), self.path) + location = urljoin(current_uri, location) + return location + def is_secure(self): return os.environ.get("HTTPS") == "on" diff --git a/django/test/testcases.py b/django/test/testcases.py index baa6e7bb19..6b7714ec7b 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -84,12 +84,8 @@ class TestCase(unittest.TestCase): self.assertEqual(response.status_code, status_code, ("Response didn't redirect as expected: Response code was %d" " (expected %d)" % (response.status_code, status_code))) - scheme, netloc, path, query, fragment = urlsplit(response['Location']) - url = path - if query: - url += '?' + query - if fragment: - url += '#' + fragment + url = response['Location'] + scheme, netloc, path, query, fragment = urlsplit(url) self.assertEqual(url, expected_url, "Response redirected to '%s', expected '%s'" % (url, expected_url)) |
