Django

Code

Ticket #2407: cgi.2.py

File cgi.2.py, 2.8 kB (added by Thomas Güttler, 3 years ago)

Changes to cgi.py: include SCRIPT_NAME in PATH_INFO and connect stdout to stderr (print to logfile)

Line 
1 """
2 CGI wrapper for Django using the WSGI protocol
3
4 Code copy/pasted from PEP-0333 and then tweaked to serve django.
5 http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
6
7 This Script is from: http://code.djangoproject.com/ticket/2407
8
9 Copy this script do django/core/servers/cgi.py
10 """
11
12 import os, sys
13 import django.core.handlers.wsgi
14
15 def runcgi():
16     environ                      = dict(os.environ.items())
17
18     # Django needs a PATH_INFO which includes the SCRIPT_NAME
19     # See http://code.djangoproject.com/ticket/285
20     # You need to edit urls.py to include the path:
21     #
22     # Example:
23     # urlpatterns = patterns(
24     #    '',
25     #    (r'^cgi-bin/django/admin/', include('django.contrib.admin.urls')),
26     #    )
27    
28     environ['PATH_INFO']         = "%s%s" % (environ['SCRIPT_NAME'], environ.get('PATH_INFO', ""))
29    
30     environ['wsgi.input']        = sys.stdin
31     environ['wsgi.errors']       = sys.stderr
32     environ['wsgi.version']      = (1,0)
33     environ['wsgi.multithread']  = False
34     environ['wsgi.multiprocess'] = True
35     environ['wsgi.run_once']     = True
36
37     application = django.core.handlers.wsgi.WSGIHandler()
38    
39     if environ.get('HTTPS','off') in ('on','1'):
40         environ['wsgi.url_scheme'] = 'https'
41     else:
42         environ['wsgi.url_scheme'] = 'http'
43    
44     headers_set  = []
45     headers_sent = []
46
47     toclient=sys.stdout
48     sys.stdout=sys.stderr # print should go to stderr (logfile)
49    
50     def write(data):
51         if not headers_set:
52              raise AssertionError("write() before start_response()")
53        
54         elif not headers_sent:
55              # Before the first output, send the stored headers
56              status, response_headers = headers_sent[:] = headers_set
57              toclient.write('Status: %s\r\n' % status)
58              for header in response_headers:
59                  toclient.write('%s: %s\r\n' % header)
60              toclient.write('\r\n')
61         toclient.write(data)
62         toclient.flush()
63        
64     def start_response(status,response_headers,exc_info=None):
65         if exc_info:
66             try:
67                 if headers_sent:
68                     # Re-raise original exception if headers sent
69                     raise exc_info[0], exc_info[1], exc_info[2]
70             finally:
71                 exc_info = None     # avoid dangling circular ref
72         elif headers_set:
73             raise AssertionError("Headers already set!")
74        
75         headers_set[:] = [status,response_headers]
76         return write
77    
78     result = application(environ, start_response)
79     try:
80         for data in result:
81             if data:    # don't send headers until body appears
82                 write(data)
83         if not headers_sent:
84             write('')   # send headers now if body was empty
85     finally:
86         if hasattr(result,'close'):
87             result.close()