[PATCH 5 of 5 postargs] http: support sending hgargs via POST body instead of in GET or headers
Augie Fackler
raf at durin42.com
Mon Mar 14 20:58:54 EDT 2016
Thanks for the review. I answered your question about implementing
this for unbundle, please feel encouraged to ask questions if I wasn't
clear enough.
On Mon, Mar 14, 2016 at 03:07:04PM -0700, Martin von Zweigbergk wrote:
> On Fri, Mar 11, 2016 at 8:55 AM, Augie Fackler <raf at durin42.com> wrote:
> > # HG changeset patch
> > # User Augie Fackler <augie at google.com>
> > # Date 1457714220 18000
> > # Fri Mar 11 11:37:00 2016 -0500
> > # Node ID 6782893562a73dc56f4184c3967775178c5bdfb4
> > # Parent efcc8e438753cddf5af209ae812f77c2affead07
> > # EXP-Topic batch
> > http: support sending hgargs via POST body instead of in GET or headers
[...]
> > diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py
> > --- a/mercurial/hgweb/protocol.py
> > +++ b/mercurial/hgweb/protocol.py
> > @@ -45,6 +45,9 @@ class webproto(wireproto.abstractserverp
> > return [data[k] for k in keys]
> > def _args(self):
> > args = self.req.form.copy()
>
> When using GET, these arguments are combined with the ones in HgArgs.
> Is that just for legacy clients, or why do we not need it for POST? (I
> read something about that in httppeer._callpush().)
Good catch.
>
> > + postlen = int(self.req.env.get('HTTP_X_HGARGS_POST', 0))
> > + if postlen:
> > + return cgi.parse_qs(self.req.read(postlen))
>
> Similar question here: For GET, we pass keep_blank_values=True to
> parse_qs(). Can there not be empty values from recent hg clients?
Good catch.
>
> Should we document that these things only apply to old clients?
>
> > chunks = []
> > i = 1
> > while True:
> > diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
> > --- a/mercurial/httppeer.py
> > +++ b/mercurial/httppeer.py
> > @@ -97,7 +97,22 @@ class httppeer(wireproto.wirepeer):
> > self.ui.debug("sending %s command\n" % cmd)
> > q = [('cmd', cmd)]
> > headersize = 0
> > - if True:
> > + # Important: don't use self.capable() here or else you end up
> > + # with infinite recursion when trying to look up capabilities
> > + # for the first time.
> > + postargsok = self.caps is not None and 'httppostargs' in self.caps
>
> Do you think "cmd != 'capabilities' and self.capable('httppostargs')"
> would be better? That form seems to assume less about the ordering of
> commands; it should allow POST'ing HgArgs even if 'capabilities' had
> not been called before the current command (whatever that may be). I
> guess it's mostly a hypothetical issue at this point (or maybe not; I
> don't know the signalling well enough).
As far as I know, that's entirely hypothetical.
>
> > + # TODO: support for httppostargs when data is a file-like
> > + # object rather than a basestring
>
> How do you imagine we (probably I) would do that? Do I make
> _callpush() prepend the serialized HgArgs to the bundle file?
The rough guess I had was to make a file-like type that prepended some
data to a file-like type.
class prepender(object):
def __init__(self, prefix, fp):
self._prefix_pointer = 0
self._prefix = prefix
self._fp = fp
def read(self, amt):
if self._prefix_pointer >= len(self._prefix):
return self._fp.read(amt)
ret = self._prefix[self._prefix_pointer:amt]
self._prefix_pointer += len(ret)
if len(ret) < amt:
ret += self._fp.read(amt - len(ret))
return ret
implementing prepender.seek() is left as an exercise for the
reader. Also testing, because I wrote that in my mailer and didn't
even check to see if it's valid Python.
>
> > + canmungedata = not data or isinstance(data, basestring)
> > + if postargsok and canmungedata:
[...]
> > # If you are writing an extension and consider wrapping this function. Wrap
> > diff --git a/tests/test-wireproto.t b/tests/test-wireproto.t
> > --- a/tests/test-wireproto.t
> > +++ b/tests/test-wireproto.t
> > @@ -19,7 +19,12 @@ Local:
> >
> > HTTP:
> >
> > - $ hg serve -R repo -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
> > + $ cat >> $HGRCPATH <<EOF
> > + > [experimental]
> > + > httppostargs = true
> > + > EOF
> > +
> > + $ hg serve -R repo -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
>
> nit: why not use "--config experimental.httppostargs=true" to save a
> few line here not have to reset it for the next test?
Sure, fixed in the resend.
More information about the Mercurial-devel
mailing list