# HG changeset patch # User Peter Arrenbrecht # Date 2011-03-22 06:38:32 # Node ID 3458c15ab2f03729ed9a762de11cef55ad95c385 # Parent 9c4e04fe267eedddbfe964227948b5bc501d3027 wireproto: fix handling of '*' args for HTTP and SSH diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py --- a/mercurial/hgweb/protocol.py +++ b/mercurial/hgweb/protocol.py @@ -22,7 +22,7 @@ class webproto(object): if k == '*': star = {} for key in self.req.form.keys(): - if key not in keys: + if key != 'cmd' and key not in keys: star[key] = self.req.form[key][0] data['*'] = star else: diff --git a/mercurial/sshrepo.py b/mercurial/sshrepo.py --- a/mercurial/sshrepo.py +++ b/mercurial/sshrepo.py @@ -119,9 +119,24 @@ class sshrepository(wireproto.wirereposi def _callstream(self, cmd, **args): self.ui.debug("sending %s command\n" % cmd) self.pipeo.write("%s\n" % cmd) - for k, v in sorted(args.iteritems()): + _func, names = wireproto.commands[cmd] + keys = names.split() + wireargs = {} + for k in keys: + if k == '*': + wireargs['*'] = args + break + else: + wireargs[k] = args[k] + del args[k] + for k, v in sorted(wireargs.iteritems()): self.pipeo.write("%s %d\n" % (k, len(v))) - self.pipeo.write(v) + if isinstance(v, dict): + for dk, dv in v.iteritems(): + self.pipeo.write("%s %d\n" % (dk, len(dv))) + self.pipeo.write(dv) + else: + self.pipeo.write(v) self.pipeo.flush() return self.pipei diff --git a/mercurial/sshserver.py b/mercurial/sshserver.py --- a/mercurial/sshserver.py +++ b/mercurial/sshserver.py @@ -30,17 +30,18 @@ class sshserver(object): for n in xrange(len(keys)): argline = self.fin.readline()[:-1] arg, l = argline.split() - val = self.fin.read(int(l)) if arg not in keys: raise util.Abort("unexpected parameter %r" % arg) if arg == '*': star = {} - for n in xrange(int(l)): + for k in xrange(int(l)): + argline = self.fin.readline()[:-1] arg, l = argline.split() val = self.fin.read(int(l)) star[arg] = val data['*'] = star else: + val = self.fin.read(int(l)) data[arg] = val return [data[k] for k in keys] diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -161,6 +161,17 @@ def dispatch(repo, proto, command): args = proto.getargs(spec) return func(repo, proto, *args) +def options(cmd, keys, others): + opts = {} + for k in keys: + if k in others: + opts[k] = others[k] + del others[k] + if others: + sys.stderr.write("abort: %s got unexpected arguments %s\n" + % (cmd, ",".join(others))) + return opts + def between(repo, proto, pairs): pairs = [decodelist(p, '-') for p in pairs.split(" ")] r = [] @@ -208,8 +219,10 @@ def changegroupsubset(repo, proto, bases cg = repo.changegroupsubset(bases, heads, 'serve') return streamres(proto.groupchunks(cg)) -def debugwireargs(repo, proto, one, two): - return repo.debugwireargs(one, two) +def debugwireargs(repo, proto, one, two, others): + # only accept optional args from the known set + opts = options('debugwireargs', ['three', 'four'], others) + return repo.debugwireargs(one, two, **opts) def heads(repo, proto): h = repo.heads() @@ -355,7 +368,7 @@ commands = { 'capabilities': (capabilities, ''), 'changegroup': (changegroup, 'roots'), 'changegroupsubset': (changegroupsubset, 'bases heads'), - 'debugwireargs': (debugwireargs, 'one two'), + 'debugwireargs': (debugwireargs, 'one two *'), 'heads': (heads, ''), 'hello': (hello, ''), 'listkeys': (listkeys, 'namespace'), diff --git a/tests/test-wireproto.t b/tests/test-wireproto.t --- a/tests/test-wireproto.t +++ b/tests/test-wireproto.t @@ -7,6 +7,10 @@ Setup repo: Local: + $ hg debugwireargs repo eins zwei --three drei --four vier + eins zwei drei vier + $ hg debugwireargs repo eins zwei --four vier + eins zwei None vier $ hg debugwireargs repo eins zwei eins zwei None None @@ -15,10 +19,20 @@ HTTP: $ hg serve -R repo -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log $ cat hg1.pid >> $DAEMON_PIDS + $ hg debugwireargs http://localhost:$HGPORT/ un deux trois quatre + un deux trois quatre + $ hg debugwireargs http://localhost:$HGPORT/ eins zwei --four vier + eins zwei None vier $ hg debugwireargs http://localhost:$HGPORT/ eins zwei eins zwei None None $ cat access.log * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob) + * - - [*] "GET /?cmd=debugwireargs&four=quatre&one=un&three=trois&two=deux HTTP/1.1" 200 - (glob) + * - - [*] "GET /?cmd=debugwireargs&four=quatre&one=un&three=trois&two=deux HTTP/1.1" 200 - (glob) + * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob) + * - - [*] "GET /?cmd=debugwireargs&four=vier&one=eins&two=zwei HTTP/1.1" 200 - (glob) + * - - [*] "GET /?cmd=debugwireargs&four=vier&one=eins&two=zwei HTTP/1.1" 200 - (glob) + * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob) * - - [*] "GET /?cmd=debugwireargs&one=eins&two=zwei HTTP/1.1" 200 - (glob) * - - [*] "GET /?cmd=debugwireargs&one=eins&two=zwei HTTP/1.1" 200 - (glob) @@ -37,6 +51,10 @@ SSH (try to exercise the ssh functionali > sys.exit(bool(r)) > EOF + $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo uno due tre quattro + uno due tre quattro + $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo eins zwei --four vier + eins zwei None vier $ hg debugwireargs --ssh "python ./dummyssh" ssh://user@dummy/repo eins zwei eins zwei None None