| | 25 | |
| | 26 | #{ WSGI streams |
| | 27 | |
| | 28 | |
| | 29 | class 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 | |
| | 41 | class 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 | |
| | 64 | class 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 | |
| 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 | |