Ticket #2407: django.cgi

File django.cgi, 3.4 KB (added by Paul Sargent, 9 years ago)

An alternative cgi script to Martin's using extisting WSGI

Line 
1#!/usr/bin/env python
2# encoding: utf-8
3"""
4django.cgi
5
6A simple cgi script which uses the django WSGI to serve requests.
7
8Code copy/pasted from PEP-0333 and then tweaked to serve django.
9http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
10
11This script assumes django is on your sys.path, and that your site code is at
12/home/mycode/mysite. Copy this script into your cgi-bin directory (or do
13whatever you need to to make a cgi script executable on your system), and then
14update the paths at the bottom of this file to suit your site.
15
16This is probably the slowest way to serve django pages, as the python
17interpreter, the django code-base and your site code has to be loaded every
18time a request is served. FCGI and mod_python solve this problem, use them if
19you can.
20
21In order to speed things up it may be worth experimenting with running
22uncompressed zips on the sys.path for django and the site code, as this can be
23(theorectically) faster. See PEP-0273 (specifically Benchmarks).
24http://www.python.org/dev/peps/pep-0273/
25
26Make sure all python files are compiled in your code base. See
27http://docs.python.org/lib/module-compileall.html
28
29"""
30
31import os, sys 
32# insert a sys.path.append("whatever") in here if django is not
33# on your sys.path.
34import django.core.handlers.wsgi
35
36def run_with_cgi(application):
37   
38    environ                      = dict(os.environ.items())
39    environ['wsgi.input']        = sys.stdin
40    environ['wsgi.errors']       = sys.stderr
41    environ['wsgi.version']      = (1,0)
42    environ['wsgi.multithread']  = False
43    environ['wsgi.multiprocess'] = True
44    environ['wsgi.run_once']     = True
45   
46    if environ.get('HTTPS','off') in ('on','1'):
47        environ['wsgi.url_scheme'] = 'https'
48    else:
49        environ['wsgi.url_scheme'] = 'http'
50   
51    headers_set  = []
52    headers_sent = []
53   
54    def write(data):
55        if not headers_set:
56             raise AssertionError("write() before start_response()")
57       
58        elif not headers_sent:
59             # Before the first output, send the stored headers
60             status, response_headers = headers_sent[:] = headers_set
61             sys.stdout.write('Status: %s\r\n' % status)
62             for header in response_headers:
63                 sys.stdout.write('%s: %s\r\n' % header)
64             sys.stdout.write('\r\n')
65       
66        sys.stdout.write(data)
67        sys.stdout.flush()
68   
69    def start_response(status,response_headers,exc_info=None):
70        if exc_info:
71            try:
72                if headers_sent:
73                    # Re-raise original exception if headers sent
74                    raise exc_info[0], exc_info[1], exc_info[2]
75            finally:
76                exc_info = None     # avoid dangling circular ref
77        elif headers_set:
78            raise AssertionError("Headers already set!")
79       
80        headers_set[:] = [status,response_headers]
81        return write
82   
83    result = application(environ, start_response)
84    try:
85        for data in result:
86            if data:    # don't send headers until body appears
87                write(data)
88        if not headers_sent:
89            write('')   # send headers now if body was empty
90    finally:
91        if hasattr(result,'close'):
92            result.close()
93
94# Change this to the directory above your site code.
95sys.path.append("/home/mycode")
96# Change mysite to the name of your site package
97os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
98run_with_cgi(django.core.handlers.wsgi.WSGIHandler())
Back to Top