Moved the iterproxy to an optionally usable preiter in wrw.util.
[wrw.git] / wrw / dispatch.py
1 import sys, traceback
2 import env, req, proto
3
4 __all__ = ["restart"]
5
6 class restart(Exception):
7     def handle(self, req):
8         pass
9
10 def mangle(result):
11     try:
12         iter(result)
13     except TypeError:
14         pass
15     else:
16         return result
17     return [str(result)]
18
19 def defaulterror(req, excinfo):
20     import resp
21     traceback.print_exception(*excinfo)
22     raise resp.httperror(500)
23
24 def wraphandler(handler, excinfo):
25     def wrapped(req):
26         return handler(req, excinfo)
27     return wrapped
28
29 errorhandler = env.var(defaulterror)
30
31 def handle(req, startreq, handler):
32     eh = errorhandler.val
33     try:
34         resp = [""]
35         while True:
36             try:
37                 resp = handler(req)
38                 break
39             except restart, i:
40                 handler = i.handle
41             except Exception, i:
42                 if eh is None:
43                     raise
44                 handler = wraphandler(eh, sys.exc_info())
45                 eh = None
46         req.commit(startreq)
47         return resp
48     finally:
49         req.cleanup()
50
51 def handleenv(env, startreq, handler):
52     if not "HTTP_HOST" in env:
53         return proto.simpleerror(env, startreq, 400, "Bad Request", "Request must include Host header.")
54     r = req.origrequest(env)
55     return handle(r, startreq, handler)