Ticket #8927: django-environ-availability.patch

File django-environ-availability.patch, 4.5 KB (added by Gustavo Narea, 14 years ago)

Patch to make the WSGI available where it's missing

  • django/core/handlers/modpython.py

     
     1"""
     2mod_python handler for Django.
     3
     4Most of the code to make the handler WSGI-compliant was taken from
     5<http://www.aminus.net/browser/modpython_gateway.py> and it was in the Public
     6Domain.
     7
     8"""
    19import os
    210from pprint import pformat
    311
     12from mod_python import apache
     13
    414from django import http
    515from django.core import signals
    616from django.core.handlers.base import BaseHandler
     
    1222# settings) until after ModPythonHandler has been called; otherwise os.environ
    1323# won't be set up correctly (with respect to settings).
    1424
     25
     26#{ WSGI streams
     27
     28
     29class WSGIStream(object):
     30    """
     31    Base class for WSGI streams.
     32   
     33    See: http://www.python.org/dev/peps/pep-0333/#id19
     34   
     35    """
     36   
     37    def __init__(self, req):
     38        self.req = req
     39
     40
     41class InputStream(WSGIStream):
     42   
     43    def close(self):
     44        pass
     45   
     46    def read(self, size=-1):
     47        return self.req.read(size)
     48   
     49    def readline(self, size=-1):
     50        return self.req.readline(size)
     51   
     52    def readlines(self, hint=-1):
     53        return self.req.readlines(hint)
     54   
     55    def __iter__(self):
     56        line = self.readline()
     57        while line:
     58            yield line
     59            # Notice this won't prefetch the next line; it only
     60            # gets called if the generator is resumed.
     61            line = self.readline()
     62
     63
     64class ErrorStream(WSGIStream):
     65   
     66    def flush(self):
     67        pass
     68   
     69    def write(self, msg):
     70        self.req.log_error(msg)
     71   
     72    def writelines(self, seq):
     73        self.write(''.join(seq))
     74
     75
     76#}
     77
     78
    1579class ModPythonRequest(http.HttpRequest):
    1680    def __init__(self, req):
    1781        self._req = req
     
    36100            # naughty, but also pretty harmless.
    37101            self.path_info = u'/'
    38102        self._post_parse_error = False
     103        # Finally, let's load the WSGI environ:
     104        self._set_environ_up()
    39105
    40106    def __repr__(self):
    41107        # Since this is called as part of error handling, we need to be very
     
    62128        return smart_str(u'<ModPythonRequest\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
    63129                         (self.path, unicode(get), unicode(post),
    64130                          unicode(cookies), unicode(meta)))
    65 
     131   
     132    def _set_environ_up(self):
     133        """
     134        Define the WSGI environment dictionary and store it in the request.
     135       
     136        """
     137        self._req.add_common_vars()
     138        options = self._req.get_options()
     139        environ = dict(self._req.subprocess_env.items())
     140       
     141        if "SCRIPT_NAME" in options:
     142            # Override SCRIPT_NAME and PATH_INFO if requested.
     143            environ['SCRIPT_NAME'] = options['SCRIPT_NAME']
     144            environ['PATH_INFO'] = self._req.uri[len(options['SCRIPT_NAME']):]
     145       
     146        environ['wsgi.input'] = InputStream(self._req)
     147        environ['wsgi.errors'] = ErrorStream(self._req)
     148        environ['wsgi.version'] = (1, 0)
     149        environ['wsgi.run_once'] = False
     150        if self._req.is_https():
     151            environ['wsgi.url_scheme'] = "https"
     152        else:
     153            environ['wsgi.url_scheme'] = "http"
     154       
     155        # Threading and forking
     156        try:
     157            threaded = bool(apache.mpm_query(apache.AP_MPMQ_IS_THREADED))
     158            forked = bool(apache.mpm_query(apache.AP_MPMQ_IS_FORKED))
     159        except AttributeError:
     160            threaded = options.get("multithread", "").lower()
     161            if threaded == "on":
     162                threaded = True
     163            elif threaded == "off":
     164                threaded = False
     165            else:
     166                raise ValueError('The "multithread" option must be either '
     167                                 '"on" or "off"')
     168           
     169            forked = options.get("multiprocess", "").lower()
     170            if forked == "on":
     171                forked = True
     172            elif forked == "off":
     173                forked = False
     174            else:
     175                raise ValueError('The "multiprocess" option must be either '
     176                                 '"on" or "off"')
     177        environ['wsgi.multithread'] = threaded
     178        environ['wsgi.multiprocess'] = forked
     179       
     180        self.environ = environ
     181   
    66182    def get_full_path(self):
    67183        # RFC 3986 requires self._req.args to be in the ASCII range, but this
    68184        # doesn't always happen, so rather than crash, we defensively encode it.
Back to Top