Code

Ticket #987: redirect_absoluteuri.3.patch

File redirect_absoluteuri.3.patch, 7.2 KB (added by SmileyChris, 7 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/')