forked from simonw/djng
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdjng_old.py
152 lines (130 loc) · 5.57 KB
/
djng_old.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
Just some sketched out ideas at the moment, this code has never been executed.
"""
from django import http
from django.core import signals
from django.utils.encoding import force_unicode
from django.utils.importlib import import_module
from django.core.handlers.wsgi import STATUS_CODE_TEXT, WSGIRequest
import sys
class Handler(object):
# Changes that are always applied to a response (in this order).
response_fixes = [
http.fix_location_header,
http.conditional_content_removal,
http.fix_IE_for_attach,
http.fix_IE_for_vary,
]
request_middleware = []
response_middleware = []
exception_middleware = []
debug = False
propagate_exceptions = False
def __init__(self, router):
self.router = router
def __call__(self, environ, start_response):
try:
request = WSGIRequest(environ)
except UnicodeDecodeError:
response = http.HttpResponseBadRequest()
else:
response = self.get_response(request)
# Apply response middleware
for middleware_method in self.response_middleware:
response = middleware_method(request, response)
response = self.apply_response_fixes(request, response)
try:
status_text = STATUS_CODE_TEXT[response.status_code]
except KeyError:
status_text = 'UNKNOWN STATUS CODE'
status = '%s %s' % (response.status_code, status_text)
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append(('Set-Cookie', str(c.output(header=''))))
start_response(status, response_headers)
return response
def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest"
from django.core import exceptions, urlresolvers
# Apply request middleware
for middleware_method in self.request_middleware:
response = middleware_method(request)
if response:
return response
# Resolve and execute the view, catching any errors
try:
response = self.router(request)
except Exception, e:
# If the view raised an exception, run it through exception
# middleware, and if the exception middleware returns a
# response, use that. Otherwise, reraise the exception.
for middleware_method in self.exception_middleware:
response = middleware_method(request, e)
if response:
return response
raise
except http.Http404, e:
return self.handle_404(request, e)
except exceptions.PermissionDenied:
return self.handle_permission_denied(request)
except SystemExit:
# Allow sys.exit() to actually exit. See tickets #1023 and #4701
raise
except: # Handle everything else, including SuspiciousOperation, etc.
# Get exc_info now, in case another exception is thrown later
exc_info = sys.exc_info()
receivers = signals.got_request_exception.send(
sender=self.__class__, request=request
)
return self.handle_uncaught_exception(request, exc_info)
def handle_404(self, request, e):
if self.debug:
from django.views import debug
return debug.technical_404_response(request, e)
else:
return http.HttpResponseNotFound('<h1>404</h1>')
def handle_permission_denied(self, request):
return http.HttpResponseForbidden('<h1>Permission denied</h1>')
def handle_uncaught_exception(self, request, exc_info):
"""
Processing for any otherwise uncaught exceptions (those that will
generate HTTP 500 responses). Can be overridden by subclasses who want
customised 500 handling.
Be *very* careful when overriding this because the error could be
caused by anything, so assuming something like the database is always
available would be an error.
"""
from django.core.mail import mail_admins
if self.propagate_exceptions:
raise
if self.debug:
from django.views import debug
return debug.technical_500_response(request, *exc_info)
# When DEBUG is False, send an error message to the admins.
subject = 'Error: %s' % request.path
try:
request_repr = repr(request)
except:
request_repr = "Request repr() unavailable"
message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
mail_admins(subject, message, fail_silently=True)
# Return an HttpResponse that displays a friendly error message.
return self.handle_500(request, exc_info)
def _get_traceback(self, exc_info=None):
"Helper function to return the traceback as a string"
import traceback
return '\n'.join(
traceback.format_exception(*(exc_info or sys.exc_info()))
)
def apply_response_fixes(self, request, response):
"""
Applies each of the functions in self.response_fixes to the request
and response, modifying the response in the process. Returns the new
response.
"""
for func in self.response_fixes:
response = func(request, response)
return response
def serve(handler, host='localhost', port=6789):
from django.core.servers.basehttp import run
run(host, int(port), handler)