summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/core/handlers/base.py17
-rw-r--r--django/http/__init__.py17
-rw-r--r--django/test/testcases.py8
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))