python: Added some SCGI fixes apparently necessary for Jython.
[ashd.git] / python / ashd / scgi.py
index 9357e9d..f7ba3a8 100644 (file)
@@ -4,6 +4,10 @@ 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:
@@ -33,7 +37,8 @@ def readhead(sk):
 class reqthread(threading.Thread):
     def __init__(self, sk, handler):
         super(reqthread, self).__init__(name = "SCGI request handler")
-        self.sk = sk.dup().makefile("r+")
+        self.bsk = sk.dup()
+        self.sk = self.bsk.makefile("r+")
         self.handler = handler
 
     def run(self):
@@ -42,6 +47,7 @@ class reqthread(threading.Thread):
             self.handler(head, self.sk)
         finally:
             self.sk.close()
+            self.bsk.close()
 
 def handlescgi(sk, handler):
     t = reqthread(sk, handler)
@@ -74,20 +80,29 @@ def wrapwsgi(handler):
         resp = []
         respsent = []
 
-        def write(data):
-            if not data:
-                return
+        def flushreq():
             if not respsent:
                 if not resp:
                     raise Exception, "Trying to write data before starting response."
                 status, headers = resp
                 respsent[:] = [True]
-                sk.write("Status: %s\n" % status)
-                for nm, val in headers:
-                    sk.write("%s: %s\n" % (nm, val))
-                sk.write("\n")
-            sk.write(data)
-            sk.flush()
+                try:
+                    sk.write("Status: %s\n" % status)
+                    for nm, val in headers:
+                        sk.write("%s: %s\n" % (nm, val))
+                    sk.write("\n")
+                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:
@@ -104,9 +119,13 @@ def wrapwsgi(handler):
 
         respiter = handler(env, startreq)
         try:
-            for data in respiter:
-                write(data)
-            write("")
+            try:
+                for data in respiter:
+                    write(data)
+                if resp:
+                    flushreq()
+            except closed:
+                pass
         finally:
             if hasattr(respiter, "close"):
                 respiter.close()