X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=blobdiff_plain;f=python3%2Fashd%2Fscgi.py;fp=python3%2Fashd%2Fscgi.py;h=c00c5a3beb3e0940a20da8d11a8065628c713848;hp=8fa57676f8fdf6062e581a4e7837f1f2dc6e06e4;hb=bcad6b0c48d516ddc920b52f06083ceaa242e1ca;hpb=589987f8218c9aa61d65f582a3b3e1bbd32bda81 diff --git a/python3/ashd/scgi.py b/python3/ashd/scgi.py index 8fa5767..c00c5a3 100644 --- a/python3/ashd/scgi.py +++ b/python3/ashd/scgi.py @@ -1,13 +1,6 @@ -import sys, collections -import threading - class protoerr(Exception): pass -class closed(IOError): - def __init__(self): - super(closed, self).__init__("The client has closed the connection.") - def readns(sk): hln = 0 while True: @@ -34,115 +27,5 @@ def readhead(sk): i += 2 return ret -class reqthread(threading.Thread): - def __init__(self, sk, handler): - super(reqthread, self).__init__(name = "SCGI request handler") - self.bsk = sk.dup() - self.sk = self.bsk.makefile("rwb") - self.handler = handler - - def run(self): - try: - head = readhead(self.sk) - self.handler(head, self.sk) - finally: - self.sk.close() - self.bsk.close() - -def handlescgi(sk, handler): - t = reqthread(sk, handler) - t.start() - -def servescgi(socket, handler): - while True: - nsk, addr = socket.accept() - try: - handlescgi(nsk, handler) - finally: - nsk.close() - def decodehead(head, coding): return {k.decode(coding): v.decode(coding) for k, v in head.items()} - -def wrapwsgi(handler): - def handle(head, sk): - try: - env = decodehead(head, "utf-8") - env["wsgi.uri_encoding"] = "utf-8" - except UnicodeError: - env = decodehead(head, "latin-1") - env["wsgi.uri_encoding"] = "latin-1" - env["wsgi.version"] = 1, 0 - if "HTTP_X_ASH_PROTOCOL" in env: - env["wsgi.url_scheme"] = env["HTTP_X_ASH_PROTOCOL"] - elif "HTTPS" in env: - env["wsgi.url_scheme"] = "https" - else: - env["wsgi.url_scheme"] = "http" - env["wsgi.input"] = sk - env["wsgi.errors"] = sys.stderr - env["wsgi.multithread"] = True - env["wsgi.multiprocess"] = False - env["wsgi.run_once"] = False - - resp = [] - respsent = [] - - def recode(thing): - if isinstance(thing, collections.ByteString): - return thing - else: - return str(thing).encode("latin-1") - - def flushreq(): - if not respsent: - if not resp: - raise Exception("Trying to write data before starting response.") - status, headers = resp - respsent[:] = [True] - buf = bytearray() - buf += b"Status: " + recode(status) + b"\n" - for nm, val in headers: - buf += recode(nm) + b": " + recode(val) + b"\n" - buf += b"\n" - try: - sk.write(buf) - except IOError: - raise closed() - - def write(data): - if not data: - return - flushreq() - try: - sk.write(data) - sk.flush() - except IOError: - raise closed() - - def startreq(status, headers, exc_info = None): - if resp: - if exc_info: # Interesting, this... - try: - if respsent: - raise exc_info[1] - finally: - exc_info = None # CPython GC bug? - else: - raise Exception("Can only start responding once.") - resp[:] = status, headers - return write - - respiter = handler(env, startreq) - try: - try: - for data in respiter: - write(data) - if resp: - flushreq() - except closed: - pass - finally: - if hasattr(respiter, "close"): - respiter.close() - return handle