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