Ticket #987: redirect_absoluteuri.3.patch

File redirect_absoluteuri.3.patch, 7.2 KB (added by Chris Beaven, 17 years ago)
  • django/core/handlers/base.py

     
    33from django import http
    44import sys
    55
     6class BaseRequiredProcesses(object):
     7    def process_response(self, request, response):
     8        # Absolute URI redirects: Ensures that any redirect attempt (which uses
     9        # the HTTP Location header) to a relative location is converted to an
     10        # absolute URI, as required by RFC 2616, section 14.30.
     11        # This is only possible if the host name can be gleaned from request.
     12        if 'Location' in response.headers and http.get_host(request):
     13            response['Location'] = request.build_absolute_uri(response['Location'])
     14        return response
     15
    616class BaseHandler(object):
     17    required_processes = BaseRequiredProcesses
     18
    719    def __init__(self):
    820        self._request_middleware = self._view_middleware = self._response_middleware = self._exception_middleware = None
    921
     
    1527        """
    1628        from django.conf import settings
    1729        from django.core import exceptions
    18         self._request_middleware = []
    19         self._view_middleware = []
    20         self._response_middleware = []
    21         self._exception_middleware = []
     30
     31        middleware_classes = [self.required_processes]
    2232        for middleware_path in settings.MIDDLEWARE_CLASSES:
    2333            try:
    2434                dot = middleware_path.rindex('.')
     
    3040            except ImportError, e:
    3141                raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
    3242            try:
    33                 mw_class = getattr(mod, mw_classname)
     43                middleware_classes.append(getattr(mod, mw_classname))
    3444            except AttributeError:
    3545                raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)
    3646
     47        self._request_middleware = []
     48        self._view_middleware = []
     49        self._response_middleware = []
     50        self._exception_middleware = []
     51        for mw_class in middleware_classes:
    3752            try:
    3853                mw_instance = mw_class()
    3954            except exceptions.MiddlewareNotUsed:
    4055                continue
    41 
    4256            if hasattr(mw_instance, 'process_request'):
    4357                self._request_middleware.append(mw_instance.process_request)
    4458            if hasattr(mw_instance, 'process_view'):
  • django/http/__init__.py

     
    11import os
    22from Cookie import SimpleCookie
    33from pprint import pformat
    4 from urllib import urlencode
     4from urllib import urlencode, quote
     5from urlparse import urljoin
    56from django.utils.datastructures import MultiValueDict, FileDict
    67from django.utils.encoding import smart_str, iri_to_uri, force_unicode
    78
     
    4445    def get_full_path(self):
    4546        return ''
    4647
     48    def build_absolute_uri(self, location=None):
     49        """
     50        Builds an absolute URI from the location and the variables available in
     51        this request. If no location is specified, the absolute URI is built on
     52        ``request.get_full_path()``.
     53        """
     54        if not location:
     55            location = request.get_full_path()
     56        if not ':' in location:
     57            current_uri = '%s://%s%s' % (self.is_secure() and 'https' or 'http',
     58                                         get_host(self), self.path)
     59            location = urljoin(current_uri, location)
     60        return location
     61
    4762    def is_secure(self):
    4863        return os.environ.get("HTTPS") == "on"
    4964
  • django/test/testcases.py

     
    8484        self.assertEqual(response.status_code, status_code,
    8585            ("Response didn't redirect as expected: Response code was %d"
    8686             " (expected %d)" % (response.status_code, status_code)))
    87         scheme, netloc, path, query, fragment = urlsplit(response['Location'])
    88         url = path
    89         if query:
    90             url += '?' + query
    91         if fragment:
    92             url += '#' + fragment
     87        url = response['Location']
     88        scheme, netloc, path, query, fragment = urlsplit(url)
    9389        self.assertEqual(url, expected_url,
    9490            "Response redirected to '%s', expected '%s'" % (url, expected_url))
    9591
  • docs/request_response.txt

     
    161161
    162162   Example: ``"/music/bands/the_beatles/?print=true"``
    163163
     164``build_absolute_uri(location)``
     165   Returns an absolute URI from the location. If no location is provided, the
     166   location will be set to ``request.get_full_path()``.
     167
     168   If the location is already an absolute URI, it will not be altered,
     169   otherwise the absolute URI is built using the server variables available in
     170   this request.
     171
     172   Example: ``"http://example.com/music/bands/the_beatles/?print=true"``
     173
    164174``is_secure()``
    165175   Returns ``True`` if the request is secure; that is, if it was made with
    166176   HTTPS.
  • tests/modeltests/test_client/models.py

     
    8383    def test_redirect(self):
    8484        "GET a URL that redirects elsewhere"
    8585        response = self.client.get('/test_client/redirect_view/')
    86        
    8786        # Check that the response was a 302 (redirect)
    8887        self.assertRedirects(response, '/test_client/get_view/')
     88       
     89        client_providing_host = Client(HTTP_HOST='django.testserver')
     90        response = client_providing_host.get('/test_client/redirect_view/')
     91        # Check that the response was a 302 (redirect) with absolute URI
     92        self.assertRedirects(response, 'http://django.testserver/test_client/get_view/')
    8993   
    9094    def test_redirect_with_query(self):
    9195        "GET a URL that redirects with given GET parameters"
     
    97101    def test_permanent_redirect(self):
    98102        "GET a URL that redirects permanently elsewhere"
    99103        response = self.client.get('/test_client/permanent_redirect_view/')
    100        
    101104        # Check that the response was a 301 (permanent redirect)
    102105        self.assertRedirects(response, '/test_client/get_view/', status_code=301)
    103106
     107        client_providing_host = Client(HTTP_HOST='django.testserver')
     108        response = client_providing_host.get('/test_client/permanent_redirect_view/')
     109        # Check that the response was a 301 (permanent redirect) with absolute URI
     110        self.assertRedirects(response, 'http://django.testserver/test_client/get_view/', status_code=301)
     111
    104112    def test_redirect_to_strange_location(self):
    105113        "GET a URL that redirects to a non-200 page"
    106114        response = self.client.get('/test_client/double_redirect_view/')
Back to Top