Merge branch 'master' of ansgar.seatribe.se:/usr/local/src/wrw
[wrw.git] / wrw / dispatch.py
CommitLineData
784d41f3 1import sys, traceback
10ba659d 2from . import env, req, proto
784d41f3 3
b409a338
FT
4__all__ = ["restart"]
5
6class restart(Exception):
7 def handle(self, req):
8 pass
9
10def mangle(result):
11 try:
12 iter(result)
13 except TypeError:
14 pass
15 else:
16 return result
17 return [str(result)]
18
784d41f3 19def defaulterror(req, excinfo):
3614ca83 20 from . import resp
784d41f3 21 traceback.print_exception(*excinfo)
d1e3dec2 22 sys.stderr.flush()
784d41f3
FT
23 raise resp.httperror(500)
24
25def wraphandler(handler, excinfo):
26 def wrapped(req):
27 return handler(req, excinfo)
0f18b774 28 wrapped.__wrapped__ = handler
784d41f3
FT
29 return wrapped
30
31errorhandler = env.var(defaulterror)
32
b409a338 33def handle(req, startreq, handler):
784d41f3 34 eh = errorhandler.val
b409a338
FT
35 try:
36 resp = [""]
37 while True:
38 try:
77dd732a 39 resp = handler(req)
b409a338 40 break
c33f2d6c 41 except restart as i:
d7604bee 42 handler = i.handle
3614ca83 43 except Exception as i:
784d41f3
FT
44 if eh is None:
45 raise
46 handler = wraphandler(eh, sys.exc_info())
47 eh = None
b409a338
FT
48 req.commit(startreq)
49 return resp
50 finally:
51 req.cleanup()
7450e2fc
FT
52
53def handleenv(env, startreq, handler):
54 if not "HTTP_HOST" in env:
55 return proto.simpleerror(env, startreq, 400, "Bad Request", "Request must include Host header.")
56 r = req.origrequest(env)
57 return handle(r, startreq, handler)
d9ce6591
FT
58
59def exterror(env, startreq):
60 def handler(req):
d747233e 61 from . import resp
d9ce6591
FT
62 code = 404
63 if "Response-Code" in req.ihead:
64 try:
65 code = int(req.ihead["Response-Code"])
66 except ValueError:
67 pass
68 raise resp.httperror(code)
69 return handleenv(env, startreq, handler)