comparison mercurial/wireprotoserver.py @ 36862:ec0af9c59270

hgweb: use a multidict for holding query string parameters My intention with refactoring the WSGI code was to make it easier to read. I initially wanted to vendor and use WebOb, because it seems to be a pretty reasonable abstraction layer for WSGI. However, it isn't using relative imports and I didn't want to deal with the hassle of patching it. But that doesn't mean we can't use good ideas from WebOb. WebOb has a "multidict" data structure for holding parsed query string and POST form data. It quacks like a dict but allows you to store multiple values for each key. It offers mechanisms to return just one value, all values, or return 1 value asserting that only 1 value is set. I quite like its API. This commit implements a read-only "multidict" in the spirit of WebOb's multidict. We replace the query string attributes of our parsed request with an instance of it. Differential Revision: https://phab.mercurial-scm.org/D2776
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 10 Mar 2018 12:35:38 -0800
parents a88d68dc3ee8
children a755fd3b7146
comparison
equal deleted inserted replaced
36861:a88d68dc3ee8 36862:ec0af9c59270
77 else: 77 else:
78 data[k] = knownargs[k][0] 78 data[k] = knownargs[k][0]
79 return [data[k] for k in keys] 79 return [data[k] for k in keys]
80 80
81 def _args(self): 81 def _args(self):
82 args = util.rapply(pycompat.bytesurl, self._wsgireq.form.copy()) 82 args = self._req.qsparams.asdictoflists()
83 postlen = int(self._req.headers.get(b'X-HgArgs-Post', 0)) 83 postlen = int(self._req.headers.get(b'X-HgArgs-Post', 0))
84 if postlen: 84 if postlen:
85 args.update(urlreq.parseqs( 85 args.update(urlreq.parseqs(
86 self._req.bodyfh.read(postlen), keep_blank_values=True)) 86 self._req.bodyfh.read(postlen), keep_blank_values=True))
87 return args 87 return args
168 repo = rctx.repo 168 repo = rctx.repo
169 169
170 # HTTP version 1 wire protocol requests are denoted by a "cmd" query 170 # HTTP version 1 wire protocol requests are denoted by a "cmd" query
171 # string parameter. If it isn't present, this isn't a wire protocol 171 # string parameter. If it isn't present, this isn't a wire protocol
172 # request. 172 # request.
173 if 'cmd' not in req.querystringdict: 173 if 'cmd' not in req.qsparams:
174 return False 174 return False
175 175
176 cmd = req.querystringdict['cmd'][0] 176 cmd = req.qsparams['cmd']
177 177
178 # The "cmd" request parameter is used by both the wire protocol and hgweb. 178 # The "cmd" request parameter is used by both the wire protocol and hgweb.
179 # While not all wire protocol commands are available for all transports, 179 # While not all wire protocol commands are available for all transports,
180 # if we see a "cmd" value that resembles a known wire protocol command, we 180 # if we see a "cmd" value that resembles a known wire protocol command, we
181 # route it to a protocol handler. This is better than routing possible 181 # route it to a protocol handler. This is better than routing possible