Mercurial > hg
comparison mercurial/hgweb/server.py @ 36803:8e1556ac01bb
hgweb: validate WSGI environment dict
The wsgiref.validate module contains useful functions for validating
that various WSGI data structures are proper.
This commit adds validation of the environment dict to our built-in
HTTP server, which turns an HTTP request into an environment dict.
The check discovered that we weren't always setting QUERY_STRING,
which would cause the cgi module to fall back to sys.argv. So we
change things to always set QUERY_STRING.
The check passes on Python 2 and 3.
Differential Revision: https://phab.mercurial-scm.org/D2731
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 08 Mar 2018 09:44:27 -0800 |
parents | 7fc80c982656 |
children | 5890e5872f36 |
comparison
equal
deleted
inserted
replaced
36802:7fc80c982656 | 36803:8e1556ac01bb |
---|---|
11 import errno | 11 import errno |
12 import os | 12 import os |
13 import socket | 13 import socket |
14 import sys | 14 import sys |
15 import traceback | 15 import traceback |
16 import wsgiref.validate | |
16 | 17 |
17 from ..i18n import _ | 18 from ..i18n import _ |
18 | 19 |
19 from .. import ( | 20 from .. import ( |
20 encoding, | 21 encoding, |
126 env[r'REQUEST_URI'] = self.path | 127 env[r'REQUEST_URI'] = self.path |
127 env[r'SCRIPT_NAME'] = pycompat.sysstr(self.server.prefix) | 128 env[r'SCRIPT_NAME'] = pycompat.sysstr(self.server.prefix) |
128 env[r'PATH_INFO'] = pycompat.sysstr(path[len(self.server.prefix):]) | 129 env[r'PATH_INFO'] = pycompat.sysstr(path[len(self.server.prefix):]) |
129 env[r'REMOTE_HOST'] = self.client_address[0] | 130 env[r'REMOTE_HOST'] = self.client_address[0] |
130 env[r'REMOTE_ADDR'] = self.client_address[0] | 131 env[r'REMOTE_ADDR'] = self.client_address[0] |
131 if query: | 132 env[r'QUERY_STRING'] = query or r'' |
132 env[r'QUERY_STRING'] = query | |
133 | 133 |
134 if pycompat.ispy3: | 134 if pycompat.ispy3: |
135 if self.headers.get_content_type() is None: | 135 if self.headers.get_content_type() is None: |
136 env[r'CONTENT_TYPE'] = self.headers.get_default_type() | 136 env[r'CONTENT_TYPE'] = self.headers.get_default_type() |
137 else: | 137 else: |
164 socketserver.ThreadingMixIn) | 164 socketserver.ThreadingMixIn) |
165 env[r'wsgi.multiprocess'] = isinstance(self.server, | 165 env[r'wsgi.multiprocess'] = isinstance(self.server, |
166 socketserver.ForkingMixIn) | 166 socketserver.ForkingMixIn) |
167 env[r'wsgi.run_once'] = 0 | 167 env[r'wsgi.run_once'] = 0 |
168 | 168 |
169 wsgiref.validate.check_environ(env) | |
170 | |
169 self.saved_status = None | 171 self.saved_status = None |
170 self.saved_headers = [] | 172 self.saved_headers = [] |
171 self.length = None | 173 self.length = None |
172 self._chunked = None | 174 self._chunked = None |
173 for chunk in self.server.application(env, self._start_response): | 175 for chunk in self.server.application(env, self._start_response): |