~ubuntu-branches/ubuntu/saucy/python-django/saucy-updates

« back to all changes in this revision

Viewing changes to django/core/handlers/base.py

  • Committer: Package Import Robot
  • Author(s): Luke Faraone, Jakub Wilk, Luke Faraone
  • Date: 2013-05-09 15:10:47 UTC
  • mfrom: (1.1.21) (4.4.27 sid)
  • Revision ID: package-import@ubuntu.com-20130509151047-aqv8d71oj9wvcv8c
Tags: 1.5.1-2
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Luke Faraone ]
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from __future__ import unicode_literals
 
2
 
 
3
import logging
1
4
import sys
 
5
import types
2
6
 
3
7
from django import http
 
8
from django.conf import settings
 
9
from django.core import exceptions
 
10
from django.core import urlresolvers
4
11
from django.core import signals
5
 
from django.utils.encoding import force_unicode
 
12
from django.utils.encoding import force_text
6
13
from django.utils.importlib import import_module
7
 
from django.utils.log import getLogger
 
14
from django.utils import six
 
15
from django.views import debug
8
16
 
9
 
logger = getLogger('django.request')
 
17
logger = logging.getLogger('django.request')
10
18
 
11
19
 
12
20
class BaseHandler(object):
28
36
 
29
37
        Must be called after the environment is fixed (see __call__ in subclasses).
30
38
        """
31
 
        from django.conf import settings
32
 
        from django.core import exceptions
33
39
        self._view_middleware = []
34
40
        self._template_response_middleware = []
35
41
        self._response_middleware = []
43
49
                raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path)
44
50
            try:
45
51
                mod = import_module(mw_module)
46
 
            except ImportError, e:
 
52
            except ImportError as e:
47
53
                raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
48
54
            try:
49
55
                mw_class = getattr(mod, mw_classname)
71
77
 
72
78
    def get_response(self, request):
73
79
        "Returns an HttpResponse object for the given HttpRequest"
74
 
        from django.core import exceptions, urlresolvers
75
 
        from django.conf import settings
76
 
 
77
80
        try:
78
81
            # Setup default url resolver for this thread, this code is outside
79
82
            # the try/except so we don't get a spurious "unbound local
91
94
                        break
92
95
 
93
96
                if response is None:
94
 
                    if hasattr(request, "urlconf"):
 
97
                    if hasattr(request, 'urlconf'):
95
98
                        # Reset url resolver with a custom urlconf.
96
99
                        urlconf = request.urlconf
97
100
                        urlresolvers.set_urlconf(urlconf)
98
101
                        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
99
102
 
100
 
                    callback, callback_args, callback_kwargs = resolver.resolve(
101
 
                            request.path_info)
 
103
                    resolver_match = resolver.resolve(request.path_info)
 
104
                    callback, callback_args, callback_kwargs = resolver_match
 
105
                    request.resolver_match = resolver_match
102
106
 
103
107
                    # Apply view middleware
104
108
                    for middleware_method in self._view_middleware:
109
113
                if response is None:
110
114
                    try:
111
115
                        response = callback(request, *callback_args, **callback_kwargs)
112
 
                    except Exception, e:
 
116
                    except Exception as e:
113
117
                        # If the view raised an exception, run it through exception
114
118
                        # middleware, and if the exception middleware returns a
115
119
                        # response, use that. Otherwise, reraise the exception.
122
126
 
123
127
                # Complain if the view returned None (a common error).
124
128
                if response is None:
125
 
                    try:
126
 
                        view_name = callback.func_name # If it's a function
127
 
                    except AttributeError:
128
 
                        view_name = callback.__class__.__name__ + '.__call__' # If it's a class
 
129
                    if isinstance(callback, types.FunctionType):    # FBV
 
130
                        view_name = callback.__name__
 
131
                    else:                                           # CBV
 
132
                        view_name = callback.__class__.__name__ + '.__call__'
129
133
                    raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name))
130
134
 
131
135
                # If the response supports deferred rendering, apply template
135
139
                        response = middleware_method(request, response)
136
140
                    response = response.render()
137
141
 
138
 
            except http.Http404, e:
 
142
            except http.Http404 as e:
139
143
                logger.warning('Not Found: %s', request.path,
140
144
                            extra={
141
145
                                'status_code': 404,
142
146
                                'request': request
143
147
                            })
144
148
                if settings.DEBUG:
145
 
                    from django.views import debug
146
149
                    response = debug.technical_404_response(request, e)
147
150
                else:
148
151
                    try:
149
152
                        callback, param_dict = resolver.resolve404()
150
153
                        response = callback(request, **param_dict)
151
154
                    except:
152
 
                        try:
153
 
                            response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
154
 
                        finally:
155
 
                            signals.got_request_exception.send(sender=self.__class__, request=request)
 
155
                        signals.got_request_exception.send(sender=self.__class__, request=request)
 
156
                        response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
156
157
            except exceptions.PermissionDenied:
157
158
                logger.warning(
158
159
                    'Forbidden (Permission denied): %s', request.path,
164
165
                    callback, param_dict = resolver.resolve403()
165
166
                    response = callback(request, **param_dict)
166
167
                except:
167
 
                    try:
168
 
                        response = self.handle_uncaught_exception(request,
 
168
                    signals.got_request_exception.send(
 
169
                            sender=self.__class__, request=request)
 
170
                    response = self.handle_uncaught_exception(request,
169
171
                            resolver, sys.exc_info())
170
 
                    finally:
171
 
                        signals.got_request_exception.send(
172
 
                            sender=self.__class__, request=request)
173
172
            except SystemExit:
174
173
                # Allow sys.exit() to actually exit. See tickets #1023 and #4701
175
174
                raise
203
202
        caused by anything, so assuming something like the database is always
204
203
        available would be an error.
205
204
        """
206
 
        from django.conf import settings
207
 
 
208
205
        if settings.DEBUG_PROPAGATE_EXCEPTIONS:
209
206
            raise
210
207
 
217
214
        )
218
215
 
219
216
        if settings.DEBUG:
220
 
            from django.views import debug
221
217
            return debug.technical_500_response(request, *exc_info)
222
218
 
223
219
        # If Http500 handler is not installed, re-raise last exception
224
220
        if resolver.urlconf_module is None:
225
 
            raise exc_info[1], None, exc_info[2]
 
221
            six.reraise(*exc_info)
226
222
        # Return an HttpResponse that displays a friendly error message.
227
223
        callback, param_dict = resolver.resolve500()
228
224
        return callback(request, **param_dict)
237
233
            response = func(request, response)
238
234
        return response
239
235
 
 
236
 
 
237
def get_path_info(environ):
 
238
    """
 
239
    Returns the HTTP request's PATH_INFO as a unicode string.
 
240
    """
 
241
    path_info = environ.get('PATH_INFO', str('/'))
 
242
    # Under Python 3, strings in environ are decoded with ISO-8859-1;
 
243
    # re-encode to recover the original bytestring provided by the webserver.
 
244
    if six.PY3:
 
245
        path_info = path_info.encode('iso-8859-1')
 
246
    # It'd be better to implement URI-to-IRI decoding, see #19508.
 
247
    return path_info.decode('utf-8')
 
248
 
 
249
 
240
250
def get_script_name(environ):
241
251
    """
242
252
    Returns the equivalent of the HTTP request's SCRIPT_NAME environment
245
255
    from the client's perspective), unless the FORCE_SCRIPT_NAME setting is
246
256
    set (to anything).
247
257
    """
248
 
    from django.conf import settings
249
258
    if settings.FORCE_SCRIPT_NAME is not None:
250
 
        return force_unicode(settings.FORCE_SCRIPT_NAME)
 
259
        return force_text(settings.FORCE_SCRIPT_NAME)
251
260
 
252
261
    # If Apache's mod_rewrite had a whack at the URL, Apache set either
253
262
    # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any
254
263
    # rewrites. Unfortunately not every Web server (lighttpd!) passes this
255
264
    # information through all the time, so FORCE_SCRIPT_NAME, above, is still
256
265
    # needed.
257
 
    script_url = environ.get('SCRIPT_URL', u'')
258
 
    if not script_url:
259
 
        script_url = environ.get('REDIRECT_URL', u'')
 
266
    script_url = environ.get('SCRIPT_URL', environ.get('REDIRECT_URL', str('')))
260
267
    if script_url:
261
 
        return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
262
 
    return force_unicode(environ.get('SCRIPT_NAME', u''))
 
268
        script_name = script_url[:-len(environ.get('PATH_INFO', str('')))]
 
269
    else:
 
270
        script_name = environ.get('SCRIPT_NAME', str(''))
 
271
    # Under Python 3, strings in environ are decoded with ISO-8859-1;
 
272
    # re-encode to recover the original bytestring provided by the webserver.
 
273
    if six.PY3:
 
274
        script_name = script_name.encode('iso-8859-1')
 
275
    # It'd be better to implement URI-to-IRI decoding, see #19508.
 
276
    return script_name.decode('utf-8')