1 |
|
2 """ |
|
3 WSGI application implementation |
|
4 """ |
|
5 |
|
6 # for error reporting |
|
7 import sys, traceback |
|
8 |
|
9 # for Request/Response |
|
10 import http |
|
11 |
|
12 class Application (object) : |
|
13 """ |
|
14 Our WSGI application, implements the wsgi __call__ interface |
|
15 """ |
|
16 |
|
17 def __init__ (self, handler) : |
|
18 """ |
|
19 Initialize to use the given handler for requests |
|
20 """ |
|
21 |
|
22 self.handler = handler |
|
23 |
|
24 def handle_request (self, env, start_response) : |
|
25 """ |
|
26 The actual request handling code |
|
27 """ |
|
28 |
|
29 # build Request object |
|
30 request = http.Request(env) |
|
31 |
|
32 try : |
|
33 # request -> response using our handler |
|
34 response = self.handler.handle_request(request) |
|
35 |
|
36 except http.ResponseError, err : |
|
37 # just use the generated response |
|
38 response = err.get_response() |
|
39 |
|
40 # send response |
|
41 assert response, "No response" |
|
42 |
|
43 # send response status/headers |
|
44 start_response(response.get_status(), response.get_headers()) |
|
45 |
|
46 # send respones data |
|
47 yield response.get_data() |
|
48 |
|
49 def __call__ (self, env, start_response) : |
|
50 """ |
|
51 Wraps handle_request to trap errors |
|
52 """ |
|
53 |
|
54 try : |
|
55 # passthrough request_handler |
|
56 for chunk in self.handle_request(env, start_response) : |
|
57 yield chunk |
|
58 |
|
59 except : |
|
60 # execption info |
|
61 info = sys.exc_info() |
|
62 |
|
63 # try and send 500 ISE to browser, if no headers yet... |
|
64 start_response("500 Internal Server Error", [('Content-type', "text/plain; charset=utf8")], info) |
|
65 |
|
66 # send traceback |
|
67 yield traceback.format_exc() |
|
68 |
|