changeset 4269:10ac3ad07faa

Take the single-file cgi-adapter from flup/pep333 for fallback
author Florian Krupicka <florian.krupicka@googlemail.com>
date Wed, 06 Aug 2008 22:21:08 +0200
parents 63c1baacceea
children ab601d804f26
files MoinMoin/web/_fallback_cgi.py MoinMoin/web/cgi_interface.py
diffstat 2 files changed, 81 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/web/_fallback_cgi.py	Wed Aug 06 22:21:08 2008 +0200
@@ -0,0 +1,71 @@
+# Taken from <http://www.python.org/dev/peps/pep-0333/>
+# which was placed in the public domain.
+
+import os, sys
+
+
+__all__ = ['WSGIServer']
+
+
+class WSGIServer(object):
+
+    def __init__(self, application):
+        self.application = application
+
+    def run(self):
+
+        environ = dict(os.environ.items())
+        environ['wsgi.input']        = sys.stdin
+        environ['wsgi.errors']       = sys.stderr
+        environ['wsgi.version']      = (1,0)
+        environ['wsgi.multithread']  = False
+        environ['wsgi.multiprocess'] = True
+        environ['wsgi.run_once']     = True
+
+        if environ.get('HTTPS','off') in ('on','1'):
+            environ['wsgi.url_scheme'] = 'https'
+        else:
+            environ['wsgi.url_scheme'] = 'http'
+
+        headers_set = []
+        headers_sent = []
+
+        def write(data):
+            if not headers_set:
+                 raise AssertionError("write() before start_response()")
+
+            elif not headers_sent:
+                 # Before the first output, send the stored headers
+                 status, response_headers = headers_sent[:] = headers_set
+                 sys.stdout.write('Status: %s\r\n' % status)
+                 for header in response_headers:
+                     sys.stdout.write('%s: %s\r\n' % header)
+                 sys.stdout.write('\r\n')
+
+            sys.stdout.write(data)
+            sys.stdout.flush()
+
+        def start_response(status,response_headers,exc_info=None):
+            if exc_info:
+                try:
+                    if headers_sent:
+                        # Re-raise original exception if headers sent
+                        raise exc_info[0], exc_info[1], exc_info[2]
+                finally:
+                    exc_info = None     # avoid dangling circular ref
+            elif headers_set:
+                raise AssertionError("Headers already set!")
+
+            headers_set[:] = [status,response_headers]
+            return write
+
+        result = self.application(environ, start_response)
+        try:
+            for data in result:
+                if data:    # don't send headers until body appears
+                    write(data)
+            if not headers_sent:
+                write('')   # send headers now if body was empty
+        finally:
+            if hasattr(result,'close'):
+                result.close()
--- a/MoinMoin/web/cgi_interface.py	Tue Aug 05 22:39:54 2008 +0200
+++ b/MoinMoin/web/cgi_interface.py	Wed Aug 06 22:21:08 2008 +0200
@@ -28,11 +28,13 @@
                             "to a unix socket. Default: localhost"))
     parser.set_default('interface', 'localhost')
 
+    cgi_fallback = False
+
     try:
         from flup.server.fcgi import WSGIServer
     except ImportError:
-        # TODO: insert some fallback here
-        pass
+        from MoinMoin.web._fallback_cgi import WSGIServer
+        cgi_fallback = True
 
     options, args = parser.parse_args()
 
@@ -46,7 +48,12 @@
         kwargs['bindAddress'] = options.interface
 
     app = make_application()
-    WSGIServer(app, **kwargs).run()
+    if not cgi_fallback:
+        WSGIServer(app, **kwargs).run()
+    else:
+        if 'bindAddress' in kwargs:
+            logging.warning('Cannot bind to socket when running with CGI fallback')
+        WSGIServer(app).run()
 
 if __name__ == '__main__':
     run()