root/django/trunk/middleware/urlmiddleware.py

Revision 108, 4.4 kB (checked in by steadicat, 12 months ago)

Fixed not to use sessions unnecessarily

  • Property svn:eol-style set to native
  • Property svn:keywords set to
    Id
    URL
    Date
    Rev
    Author
Line 
1"""
2URL Middleware
3Stefano J. Attardi (attardi.org)
4
5$Id$
6$URL$
7
8Cleans up urls by adding/removing trailing slashes, adding/removing
9the www. prefix, and allowing the language to be set from the url.
10
11If APPEND_SLASH is set to False, trailing slashes are removed from the
12urls, except for urls which have an explicit trailing slash in
13urls.py, in which case a trailing slash is added.
14
15If REMOVE_WWW is set to True, the www. prefix is removed.
16
17Finally, ?lang=xx can be appended to any url to override the default
18language setting. This override is remembered for the following
19requests. For example, /article?lang=it would show the article in
20Italian regardless of brower settings or cookies, and any following
21request to the site would be shown in Italian by default.
22
23Changelog
24
251.3.3
26Fixed a bug which made the middleware use sessions for languages even
27when they were not used by anything else.
28
291.3.2
30Fixed an indentation issue. Added a check for those backends
31which set an empty path (e.g. runfcgi).
32
331.3.1
34Added support for running in a test
35suite (doesn't assume that HTTP_HOST is set)
36
371.3
38Only use sessions for the language preference if the session
39cookie has already been set (regardless of whether session middleware
40is active). Otherwise use the plain django_language cookie.
41Only import the FlatPages module if it is active.
42
431.2
44Added support for FlatPages.
45Switched to Django's resolve function (with workaround for when it
46returns None).
47
481.1
49Various bugfixes.
50
511.0
52First release.
53"""
54__version__ = "1.3.3"
55__license__ = "Python"
56__copyright__ = "Copyright (C) 2006-2008, Stefano J. Attardi"
57__author__ = "Stefano J. Attardi <http://attardi.org/>"
58__contributors__ = ["Antonio Cavedoni <http://cavedoni.com/>"]
59
60from django.conf import settings
61from django.http import HttpResponseRedirect, Http404
62from django.core.urlresolvers import resolve
63from django.utils.translation import check_for_language
64import os
65
66class UrlMiddleware:
67
68    def process_request(self, request):
69
70        # Change the language setting for the current page
71        if "lang" in request.GET and check_for_language(request.GET["lang"]):
72            if 'sessionid' in request.COOKIES:
73                request.session["django_language"] = request.GET["lang"]
74            else:
75                request.COOKIES["django_language"] = request.GET["lang"]
76
77        # work-around for runfcgi
78        if request.path == "": request.path = "/"
79
80        # Check for a redirect based on settings.APPEND_SLASH and settings.PREPEND_WWW
81        old_url = [request.META.get("HTTP_HOST", "localhost"), request.path]
82        new_url = old_url[:]
83
84        # if REMOVE_WWW is True, remove the www. from the urls if necessary
85        if hasattr(settings, "REMOVE_WWW") and settings.REMOVE_WWW and old_url[0].startswith("www."):
86            new_url[0] = old_url[0][4:]
87
88        if hasattr(settings, "APPEND_SLASH") and not settings.APPEND_SLASH:
89            # if the url is not found, try with(out) the trailing slash
90            if old_url[1] != "/" and not self._urlExists(old_url[1]):
91
92                if old_url[1][-1] == "/":
93                    other = old_url[1][:-1]
94                else:
95                    other = old_url[1] + "/"
96
97                if self._urlExists(other):
98                    new_url[1] = other
99
100        if new_url != old_url:
101            # Redirect
102            newurl = "%s://%s%s" % (os.environ.get("HTTPS") == "on" and "https" or "http", new_url[0], new_url[1])
103            if request.GET:
104                newurl += "?" + request.GET.urlencode()
105
106            return HttpResponseRedirect(newurl)
107
108        return None
109
110    def process_response(self, request, response):
111
112        # Change the language setting for future pages
113        if "lang" in request.GET and check_for_language(request.GET["lang"]):
114            if 'sessionid' in request.COOKIES:
115                request.session["django_language"] = request.GET["lang"]
116            else:
117                response.set_cookie("django_language", request.GET["lang"])
118
119        return response
120
121    def _urlExists(self, path):
122        try:
123            if resolve(path) is None: raise Http404 # None?!? You mean 404...
124            return True
125        except Http404:
126            # check for flatpages
127            if "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware" in settings.MIDDLEWARE_CLASSES:
128                from django.contrib.flatpages.models import FlatPage
129                return FlatPage.objects.filter(url=path, sites__id=settings.SITE_ID).count() == 1
Note: See TracBrowser for help on using the browser.