Django

Code

Changeset 6852

Show
Ignore:
Timestamp:
12/02/07 17:25:55 (7 months ago)
Author:
mtredinnick
Message:

Fixed #3228 -- Added new APPEND_SLASH handling behaviour in the common middleware. Makes customisation a bit easier. Thanks, Mihai Preda and Andy Gayton.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r6845 r6852  
    134134    gandalf@owca.info 
    135135    Marc Garcia <marc.garcia@accopensys.com> 
     136    Andy Gayton <andy-django@thecablelounge.com> 
    136137    Baishampayan Ghose 
    137138    Dimitris Glezos <dimitris@glezos.com> 
     
    256257    Luke Plant <http://lukeplant.me.uk/> 
    257258    plisk 
     259    Mihai Preda <mihai_preda@yahoo.com> 
    258260    Daniel Poelzleithner <http://poelzi.org/> 
    259261    polpak@yahoo.com 
  • django/trunk/django/middleware/common.py

    r6553 r6852  
    66from django.core.mail import mail_managers 
    77from django.utils.http import urlquote 
     8from django.core import urlresolvers 
    89 
    910class CommonMiddleware(object): 
     
    1617          this middleware appends missing slashes and/or prepends missing 
    1718          "www."s. 
     19 
     20            - If APPEND_SLASH is set and the initial URL doesn't end with a 
     21              slash, and it is not found in urlpatterns, a new URL is formed by 
     22              appending a slash at the end. If this new URL is found in 
     23              urlpatterns, then an HTTP-redirect is returned to this new URL; 
     24              otherwise the initial URL is processed as usual.  
    1825 
    1926        - ETags: If the USE_ETAGS setting is set, ETags will be calculated from 
     
    3441                    return http.HttpResponseForbidden('<h1>Forbidden</h1>') 
    3542 
    36         # Check for a redirect based on settings.APPEND_SLASH and settings.PREPEND_WWW 
     43        # Check for a redirect based on settings.APPEND_SLASH 
     44        # and settings.PREPEND_WWW 
    3745        host = request.get_host() 
    3846        old_url = [host, request.path] 
    3947        new_url = old_url[:] 
    40         if settings.PREPEND_WWW and old_url[0] and not old_url[0].startswith('www.'): 
     48 
     49        if (settings.PREPEND_WWW and old_url[0] and 
     50                not old_url[0].startswith('www.')): 
    4151            new_url[0] = 'www.' + old_url[0] 
    42         # Append a slash if append_slash is set and the URL doesn't have a 
    43         # trailing slash or a file extension. 
    44         if settings.APPEND_SLASH and (not old_url[1].endswith('/')) and ('.' not in old_url[1].split('/')[-1]): 
    45             new_url[1] = new_url[1] + '/' 
    46             if settings.DEBUG and request.method == 'POST': 
    47                 raise RuntimeError, "You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to %s%s (note the trailing slash), or set APPEND_SLASH=False in your Django settings." % (new_url[0], new_url[1]) 
     52 
     53        # Append a slash if APPEND_SLASH is set and the URL doesn't have a 
     54        # trailing slash and there is no pattern for the current path 
     55        if settings.APPEND_SLASH and (not old_url[1].endswith('/')): 
     56            try: 
     57                urlresolvers.resolve(request.path) 
     58            except urlresolvers.Resolver404: 
     59                new_url[1] = new_url[1] + '/' 
     60                if settings.DEBUG and request.method == 'POST': 
     61                    raise RuntimeError, ("" 
     62                    "You called this URL via POST, but the URL doesn't end " 
     63                    "in a slash and you have APPEND_SLASH set. Django can't " 
     64                    "redirect to the slash URL while maintaining POST data. " 
     65                    "Change your form to point to %s%s (note the trailing " 
     66                    "slash), or set APPEND_SLASH=False in your Django " 
     67                    "settings.") % (new_url[0], new_url[1]) 
     68 
    4869        if new_url != old_url: 
    49             # Redirect 
    50             if new_url[0]: 
    51                 newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], urlquote(new_url[1])) 
     70            # Redirect if the target url exists 
     71            try: 
     72                urlresolvers.resolve(new_url[1]) 
     73            except urlresolvers.Resolver404: 
     74                pass 
    5275            else: 
    53                 newurl = urlquote(new_url[1]) 
    54             if request.GET: 
    55                 newurl += '?' + request.GET.urlencode() 
    56             return http.HttpResponsePermanentRedirect(newurl) 
     76                if new_url[0]: 
     77                    newurl = "%s://%s%s" % ( 
     78                        request.is_secure() and 'https' or 'http', 
     79                        new_url[0], urlquote(new_url[1])) 
     80                else: 
     81                    newurl = urlquote(new_url[1]) 
     82                if request.GET: 
     83                    newurl += '?' + request.GET.urlencode() 
     84                return http.HttpResponsePermanentRedirect(newurl) 
    5785 
    5886        return None 
  • django/trunk/docs/middleware.txt

    r6678 r6852  
    5959 
    6060* Performs URL rewriting based on the ``APPEND_SLASH`` and ``PREPEND_WWW`` 
    61   settings. If ``APPEND_SLASH`` is ``True``, URLs that lack a trailing 
    62   slash will be redirected to the same URL with a trailing slash, unless the 
    63   last component in the path contains a period. So ``foo.com/bar`` is 
    64   redirected to ``foo.com/bar/``, but ``foo.com/bar/file.txt`` is passed 
    65   through unchanged. 
     61  settings. 
     62 
     63  If ``APPEND_SLASH`` is ``True`` and the initial URL doesn't end with a slash, 
     64  and it is not found in urlpatterns, a new URL is formed by appending a slash 
     65  at the end. If this new URL is found in urlpatterns, then an HTTP-redirect is 
     66  returned to this new URL; otherwise the initial URL is processed as usual. 
     67 
     68  So ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if you do not 
     69  have a valid urlpattern for ``foo.com/bar``, and do have a valid urlpattern 
     70  for ``foo.com/bar/``. 
     71 
     72  **New in Django development version:** The behaviour of ``APPEND_SLASH`` has 
     73  changed slightly in the development version (it didn't used to check to see 
     74  if the pattern was matched in the URL patterns). 
    6675 
    6776  If ``PREPEND_WWW`` is ``True``, URLs that lack a leading "www." will be 
  • django/trunk/tests/urls.py

    r6370 r6852  
    1515    # django built-in views 
    1616    (r'^views/', include('regressiontests.views.urls')), 
     17 
     18    # test urlconf for middleware tests 
     19    (r'^middleware/', include('regressiontests.middleware.urls')), 
    1720)