| 1 | import sys, traceback |
| 2 | from . 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 | from . import resp |
| 21 | traceback.print_exception(*excinfo) |
| 22 | sys.stderr.flush() |
| 23 | raise resp.httperror(500) |
| 24 | |
| 25 | def wraphandler(handler, excinfo): |
| 26 | def wrapped(req): |
| 27 | return handler(req, excinfo) |
| 28 | wrapped.__wrapped__ = handler |
| 29 | return wrapped |
| 30 | |
| 31 | errorhandler = env.var(defaulterror) |
| 32 | |
| 33 | def handle(req, startreq, handler): |
| 34 | eh = errorhandler.val |
| 35 | try: |
| 36 | resp = [""] |
| 37 | while True: |
| 38 | try: |
| 39 | resp = handler(req) |
| 40 | break |
| 41 | except restart as i: |
| 42 | handler = i.handle |
| 43 | except Exception as i: |
| 44 | if eh is None: |
| 45 | raise |
| 46 | handler = wraphandler(eh, sys.exc_info()) |
| 47 | eh = None |
| 48 | req.commit(startreq) |
| 49 | return resp |
| 50 | finally: |
| 51 | req.cleanup() |
| 52 | |
| 53 | def 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) |
| 58 | |
| 59 | def exterror(env, startreq): |
| 60 | def handler(req): |
| 61 | from . import resp |
| 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) |