| 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 | |