changeset 3412:91d38a790d8e

request framework: handle connection aborts gracefully
author Johannes Berg <johannes AT sipsolutions DOT net>
date Sat, 22 Mar 2008 13:54:55 +0100
parents b9b958b46ed1
children fc0f007111e9
files MoinMoin/request/__init__.py MoinMoin/request/request_cgi.py MoinMoin/request/request_cli.py MoinMoin/request/request_fcgi.py MoinMoin/request/request_modpython.py MoinMoin/request/request_standalone.py MoinMoin/request/request_twisted.py MoinMoin/request/request_wsgi.py
diffstat 8 files changed, 54 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/request/__init__.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/__init__.py	Sat Mar 22 13:54:55 2008 +0100
@@ -80,6 +80,10 @@
 class HeadersAlreadySentException(Exception):
     """ Is raised if the headers were already sent when emit_http_headers is called."""
 
+
+class RemoteClosedConnection(Exception):
+    """ Remote end closed connection during request """
+
 # Utilities
 
 def cgiMetaVariable(header, scheme='http'):
@@ -1275,11 +1279,17 @@
 
         except MoinMoinFinish:
             pass
+        except RemoteClosedConnection:
+            # at least clean up
+            pass
         except SystemExit:
             raise # fcgi uses this to terminate a thread
         except Exception, err:
-            self.fail(err)
-            self.finish()
+            try:
+                # nothing we can do about further failures!
+                self.fail(err)
+            except:
+                pass
 
         if self.cfg.log_timing:
             self.timing_log(False, action_name)
--- a/MoinMoin/request/request_cgi.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_cgi.py	Sat Mar 22 13:54:55 2008 +0100
@@ -9,7 +9,7 @@
 """
 import sys, os, cgi
 
-from MoinMoin.request import RequestBase
+from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on CGI requests """
@@ -42,7 +42,11 @@
 
     def write(self, *data):
         """ Write to output stream. """
-        sys.stdout.write(self.encode(data))
+        data = self.encode(data)
+        try:
+            sys.stdout.write(data)
+        except Exception:
+            raise RemoteClosedConnection()
 
     def flush(self):
         sys.stdout.flush()
--- a/MoinMoin/request/request_cli.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_cli.py	Sat Mar 22 13:54:55 2008 +0100
@@ -8,7 +8,7 @@
 """
 import sys
 
-from MoinMoin.request import RequestBase
+from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on command line interface and script requests """
@@ -47,7 +47,11 @@
 
     def write(self, *data):
         """ Write to output stream. """
-        sys.stdout.write(self.encode(data))
+        data = self.encode(data)
+        try:
+            sys.stdout.write(data)
+        except IOError:
+            raise RemoteClosedConnection()
 
     def flush(self):
         sys.stdout.flush()
--- a/MoinMoin/request/request_fcgi.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_fcgi.py	Sat Mar 22 13:54:55 2008 +0100
@@ -7,7 +7,7 @@
                 2003-2006 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
 """
-from MoinMoin.request import RequestBase
+from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on FastCGI requests """
@@ -44,7 +44,11 @@
 
     def write(self, *data):
         """ Write to output stream. """
-        self.fcgreq.out.write(self.encode(data))
+        data = self.encode(data)
+        try:
+            self.fcgreq.out.write(data)
+        except Exception:
+            raise RemoteClosedConnection()
 
     def flush(self):
         """ Flush output stream. """
--- a/MoinMoin/request/request_modpython.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_modpython.py	Sat Mar 22 13:54:55 2008 +0100
@@ -7,7 +7,7 @@
     @license: GNU GPL, see COPYING for details.
 """
 from MoinMoin import wikiutil
-from MoinMoin.request import RequestBase
+from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on mod_python requests """
@@ -125,7 +125,11 @@
 
     def write(self, *data):
         """ Write to output stream. """
-        self.mpyreq.write(self.encode(data))
+        data = self.encode(data)
+        try:
+            self.mpyreq.write(data)
+        except Exception:
+            raise RemoteClosedConnection()
 
     def flush(self):
         """ We can't flush it, so do nothing. """
--- a/MoinMoin/request/request_standalone.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_standalone.py	Sat Mar 22 13:54:55 2008 +0100
@@ -8,7 +8,7 @@
 """
 import cgi
 
-from MoinMoin.request import RequestBase
+from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on StandAlone Server (MoinMoin.server.server_standalone) requests """
@@ -81,7 +81,11 @@
 
     def write(self, *data):
         """ Write to output stream. """
-        self.wfile.write(self.encode(data))
+        data = self.encode(data)
+        try:
+            self.wfile.write(data)
+        except Exception:
+            raise RemoteClosedConnection()
 
     def flush(self):
         self.wfile.flush()
--- a/MoinMoin/request/request_twisted.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_twisted.py	Sat Mar 22 13:54:55 2008 +0100
@@ -7,7 +7,7 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-from MoinMoin.request import RequestBase, MoinMoinFinish
+from MoinMoin.request import RequestBase, MoinMoinFinish, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on Twisted requests """
@@ -91,7 +91,11 @@
     def write(self, *data):
         """ Write to output stream. """
         #print "request.RequestTwisted.write: data=\n" + wd
-        self.reactor.callFromThread(self.twistd.write, self.encode(data))
+        data = self.encode(data)
+        try:
+            self.reactor.callFromThread(self.twistd.write, data)
+        except Exception:
+            raise RemoteClosedConnection()
 
     def flush(self):
         pass # XXX is there a flush in twisted?
--- a/MoinMoin/request/request_wsgi.py	Sat Mar 22 13:49:57 2008 +0100
+++ b/MoinMoin/request/request_wsgi.py	Sat Mar 22 13:54:55 2008 +0100
@@ -8,7 +8,7 @@
 """
 import cgi, StringIO
 
-from MoinMoin.request import RequestBase
+from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
     """ specialized on WSGI requests """
@@ -55,7 +55,11 @@
             return self.stdin.read(n)
 
     def write(self, *data):
-        self.stdout.write(self.encode(data))
+        data = self.encode(data)
+        try:
+            self.stdout.write(data)
+        except Exception:
+            raise RemoteClosedConnection()
 
     def _emit_http_headers(self, headers):
         """ private method to send out preprocessed list of HTTP headers """