comparison mercurial/hgweb/request.py @ 45004:2632c1ed8f34 stable

hgweb: encode WSGI environment like OS environment Previously, the WSGI environment keys and values were encoded using latin-1. This resulted in a crash if a WSGI environment key or value could not be encoded using latin-1. On Unix, the OS environment is byte-based. Therefore we should do the reverse of what Python does for os.environ. On Windows, there’s no native byte-based OS environment. Therefore we should do the same as what mercurial.encoding does with the OS environment.
author Manuel Jacob <me@manueljacob.de>
date Thu, 25 Jun 2020 03:46:07 +0200
parents 839328c5a728
children 89a2afe31e82
comparison
equal deleted inserted replaced
45003:839328c5a728 45004:2632c1ed8f34
10 10
11 # import wsgiref.validate 11 # import wsgiref.validate
12 12
13 from ..thirdparty import attr 13 from ..thirdparty import attr
14 from .. import ( 14 from .. import (
15 encoding,
15 error, 16 error,
16 pycompat, 17 pycompat,
17 util, 18 util,
18 ) 19 )
19 20
160 # PEP-0333 states that environment keys and values are native strings 161 # PEP-0333 states that environment keys and values are native strings
161 # (bytes on Python 2 and str on Python 3). The code points for the Unicode 162 # (bytes on Python 2 and str on Python 3). The code points for the Unicode
162 # strings on Python 3 must be between \00000-\000FF. We deal with bytes 163 # strings on Python 3 must be between \00000-\000FF. We deal with bytes
163 # in Mercurial, so mass convert string keys and values to bytes. 164 # in Mercurial, so mass convert string keys and values to bytes.
164 if pycompat.ispy3: 165 if pycompat.ispy3:
166
165 def tobytes(s): 167 def tobytes(s):
166 if not isinstance(s, str): 168 if not isinstance(s, str):
167 return s 169 return s
168 return s.encode('latin-1') 170 if pycompat.iswindows:
171 # This is what mercurial.encoding does for os.environ on
172 # Windows.
173 return encoding.strtolocal(s)
174 else:
175 # This is what is documented to be used for os.environ on Unix.
176 return pycompat.fsencode(s)
177
169 env = {tobytes(k): tobytes(v) for k, v in pycompat.iteritems(env)} 178 env = {tobytes(k): tobytes(v) for k, v in pycompat.iteritems(env)}
170 179
171 # Some hosting solutions are emulating hgwebdir, and dispatching directly 180 # Some hosting solutions are emulating hgwebdir, and dispatching directly
172 # to an hgweb instance using this environment variable. This was always 181 # to an hgweb instance using this environment variable. This was always
173 # checked prior to d7fd203e36cc; keep doing so to avoid breaking them. 182 # checked prior to d7fd203e36cc; keep doing so to avoid breaking them.