diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -6,7 +6,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -import os +import os, zlib from mercurial import ui, hg, hook, error, encoding, templater, wireproto from common import get_mtime, ErrorResponse, permhooks from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR @@ -22,6 +22,7 @@ perms = { 'pushkey': 'push', } +HGTYPE = 'application/mercurial-0.1' class webproto(object): def __init__(self, req): self.req = req @@ -39,8 +40,17 @@ class webproto(object): else: data[k] = self.req.form[k][0] return [data[k] for k in keys] + def sendchangegroup(self, cg): + self.req.respond(HTTP_OK, HGTYPE) + z = zlib.compressobj() + while 1: + chunk = cg.read(4096) + if not chunk: + break + self.req.write(z.compress(chunk)) + self.req.write(z.flush()) + def respond(self, s): - HGTYPE = 'application/mercurial-0.1' self.req.respond(HTTP_OK, HGTYPE, length=len(s)) self.response = s diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py --- a/mercurial/hgweb/protocol.py +++ b/mercurial/hgweb/protocol.py @@ -23,43 +23,6 @@ from common import ErrorResponse, HTTP_O HGTYPE = 'application/mercurial-0.1' basecaps = 'lookup changegroupsubset branchmap pushkey'.split() -def changegroup(repo, req): - req.respond(HTTP_OK, HGTYPE) - nodes = [] - - if 'roots' in req.form: - nodes = map(bin, req.form['roots'][0].split(" ")) - - z = zlib.compressobj() - f = repo.changegroup(nodes, 'serve') - while 1: - chunk = f.read(4096) - if not chunk: - break - yield z.compress(chunk) - - yield z.flush() - -def changegroupsubset(repo, req): - req.respond(HTTP_OK, HGTYPE) - bases = [] - heads = [] - - if 'bases' in req.form: - bases = [bin(x) for x in req.form['bases'][0].split(' ')] - if 'heads' in req.form: - heads = [bin(x) for x in req.form['heads'][0].split(' ')] - - z = zlib.compressobj() - f = repo.changegroupsubset(bases, heads, 'serve') - while 1: - chunk = f.read(4096) - if not chunk: - break - yield z.compress(chunk) - - yield z.flush() - def capabilities(repo, req): caps = copy.copy(basecaps) if streamclone.allowed(repo.ui): diff --git a/mercurial/sshserver.py b/mercurial/sshserver.py --- a/mercurial/sshserver.py +++ b/mercurial/sshserver.py @@ -58,6 +58,15 @@ class sshserver(object): self.fout.write(v) self.fout.flush() + def sendchangegroup(self, changegroup): + while True: + d = changegroup.read(4096) + if not d: + break + self.fout.write(d) + + self.fout.flush() + def serve_forever(self): try: while self.serve_one(): @@ -105,34 +114,6 @@ class sshserver(object): self.lock = None return "" - def do_changegroup(self): - nodes = [] - roots = self.getarg('roots') - nodes = map(bin, roots.split(" ")) - - cg = self.repo.changegroup(nodes, 'serve') - while True: - d = cg.read(4096) - if not d: - break - self.fout.write(d) - - self.fout.flush() - - def do_changegroupsubset(self): - bases, heads = self.getargs('bases heads') - bases = [bin(n) for n in bases.split(' ')] - heads = [bin(n) for n in heads.split(' ')] - - cg = self.repo.changegroupsubset(bases, heads, 'serve') - while True: - d = cg.read(4096) - if not d: - break - self.fout.write(d) - - self.fout.flush() - def do_addchangegroup(self): '''DEPRECATED''' diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -15,7 +15,9 @@ def dispatch(repo, proto, command): return False func, spec = commands[command] args = proto.getargs(spec) - proto.respond(func(repo, proto, *args)) + r = func(repo, proto, *args) + if r != None: + proto.respond(r) return True def between(repo, proto, pairs): @@ -41,6 +43,17 @@ def branches(repo, proto, nodes): r.append(" ".join(map(hex, b)) + "\n") return "".join(r) +def changegroup(repo, proto, roots): + nodes = map(bin, roots.split(" ")) + cg = repo.changegroup(nodes, 'serve') + proto.sendchangegroup(cg) + +def changegroupsubset(repo, proto, bases, heads): + bases = [bin(n) for n in bases.split(' ')] + heads = [bin(n) for n in heads.split(' ')] + cg = repo.changegroupsubset(bases, heads, 'serve') + proto.sendchangegroup(cg) + def heads(repo, proto): h = repo.heads() return " ".join(map(hex, h)) + "\n" @@ -68,6 +81,8 @@ commands = { 'between': (between, 'pairs'), 'branchmap': (branchmap, ''), 'branches': (branches, 'nodes'), + 'changegroup': (changegroup, 'roots'), + 'changegroupsubset': (changegroupsubset, 'bases heads'), 'heads': (heads, ''), 'listkeys': (listkeys, 'namespace'), 'lookup': (lookup, 'key'), diff --git a/tests/test-clone-cgi b/tests/test-clone-cgi --- a/tests/test-clone-cgi +++ b/tests/test-clone-cgi @@ -55,7 +55,7 @@ SERVER_SIGNATURE="
Apache/2.0.53 SERVER_SOFTWARE="Apache/2.0.53 (Fedora)"; export SERVER_SOFTWARE echo % try hgweb request -QUERY_STRING="cmd=changegroup"; export QUERY_STRING +QUERY_STRING="cmd=changegroup&roots=0000000000000000000000000000000000000000"; export QUERY_STRING python hgweb.cgi >page1 2>&1 ; echo $? python "$TESTDIR/md5sum.py" page1 diff --git a/tests/test-hgweb-commands b/tests/test-hgweb-commands --- a/tests/test-hgweb-commands +++ b/tests/test-hgweb-commands @@ -50,7 +50,7 @@ echo % lookup echo % branches "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches&nodes=0000000000000000000000000000000000000000' echo % changegroup -"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup' \ +"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup&roots=0000000000000000000000000000000000000000' \ | $TESTDIR/printrepr.py echo % stream_out "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'