WSGI CGI-Server aus dem PEP333
Wird z.B. beim Colubrid 'Hello World' Beispie benutzt.
PEP333_WSGI_CGIServer.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 A simple WSGI CGI gateway taken from:
6 http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
7 (public domain)
8 """
9
10
11 import os, sys
12
13 def run_with_cgi(application):
14
15 environ = dict(os.environ.items())
16 environ['wsgi.input'] = sys.stdin
17 environ['wsgi.errors'] = sys.stderr
18 environ['wsgi.version'] = (1,0)
19 environ['wsgi.multithread'] = False
20 environ['wsgi.multiprocess'] = True
21 environ['wsgi.run_once'] = True
22
23 if environ.get('HTTPS','off') in ('on','1'):
24 environ['wsgi.url_scheme'] = 'https'
25 else:
26 environ['wsgi.url_scheme'] = 'http'
27
28 headers_set = []
29 headers_sent = []
30
31 def write(data):
32 if not headers_set:
33 raise AssertionError("write() before start_response()")
34
35 elif not headers_sent:
36 # Before the first output, send the stored headers
37 status, response_headers = headers_sent[:] = headers_set
38 sys.stdout.write('Status: %s\r\n' % status)
39 for header in response_headers:
40 sys.stdout.write('%s: %s\r\n' % header)
41 sys.stdout.write('\r\n')
42
43 sys.stdout.write(data)
44 sys.stdout.flush()
45
46 def start_response(status,response_headers,exc_info=None):
47 if exc_info:
48 try:
49 if headers_sent:
50 # Re-raise original exception if headers sent
51 raise exc_info[0], exc_info[1], exc_info[2]
52 finally:
53 exc_info = None # avoid dangling circular ref
54 elif headers_set:
55 raise AssertionError("Headers already set!")
56
57 headers_set[:] = [status,response_headers]
58 return write
59
60 result = application(environ, start_response)
61 try:
62 for data in result:
63 if data: # don't send headers until body appears
64 write(data)
65 if not headers_sent:
66 write('') # send headers now if body was empty
67 finally:
68 if hasattr(result,'close'):
69 result.close()