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