diff options
| author | ianb <devnull@localhost> | 2005-05-14 06:10:38 +0000 |
|---|---|---|
| committer | ianb <devnull@localhost> | 2005-05-14 06:10:38 +0000 |
| commit | 9f06963d1e4efa62d7e70b34151094986ae5b2c1 (patch) | |
| tree | 80ebf9bc56803280011ea27c92fe127bc38a6999 /paste/servers/cgi_wsgi.py | |
| parent | 9b267d3e23b5935b8be4fcea139186f570f6f23c (diff) | |
| download | paste-9f06963d1e4efa62d7e70b34151094986ae5b2c1.tar.gz | |
Finished making servers pluggable
Diffstat (limited to 'paste/servers/cgi_wsgi.py')
| -rw-r--r-- | paste/servers/cgi_wsgi.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/paste/servers/cgi_wsgi.py b/paste/servers/cgi_wsgi.py new file mode 100644 index 0000000..83d257c --- /dev/null +++ b/paste/servers/cgi_wsgi.py @@ -0,0 +1,113 @@ +""" +cgi WSGI server +=============== + +Usage +----- + +The CGI script is the configuration and glue for this server. +Typically you will write a CGI script like:: + + #!/usr/bin/env python + from paste.cgiserver import run_with_cgi + # Assuming app is your WSGI application object... + from myapplication import app + run_with_cgi(app) + +""" + +import os, sys + +def run_with_cgi(application, + use_cgitb=True, + redirect_stdout=False): + stdout = sys.stdout + + if use_cgitb: + import cgitb + cgitb.enable() + + environ = dict(os.environ) + 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 os.environ.get('HTTPS', 'off').lower() in ('on', '1'): + environ['wsgi.url_scheme'] = 'https' + else: + environ['wsgi.url_scheme'] = 'http' + + if redirect_stdout: + sys.stdout = sys.stderr + + headers_set = [] + headers_sent = [] + result = None + + def write(data): + assert headers_set, "write() before start_response()" + + if not headers_sent: + # Before the first output, send the stored headers + status, response_headers = headers_sent[:] = headers_set + + # See if Content-Length is given. + found = False + for name, value in response_headers: + if name.lower() == 'content-length': + found = True + break + + # If not given, try to deduce it if the iterator implements + # __len__ and is of length 1. (data will be result[0] in this + # case.) + if not found and result is not None: + try: + if len(result) == 1: + response_headers.append(('Content-Length', + str(len(data)))) + except: + pass + + stdout.write('Status: %s\r\n' % status) + for header in response_headers: + stdout.write('%s: %s\r\n' % header) + stdout.write('\r\n') + + stdout.write(data) + 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 + else: + assert not headers_set, "Headers already set!" + + headers_set[:] = [status, response_headers] + return write + + result = 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() + +if __name__ == '__main__': + def myapp(environ, start_response): + start_response('200 OK', [('Content-Type', 'text/plain')]) + return ['Hello World!\n'] + + run_with_cgi(myapp) |
