# HG changeset patch # User Matt Mackall # Date 1279139115 18000 # Node ID 4530b3307fb9ae7f24c7e3d5e7c3c172656ba686 # Parent 69248b5add469d62c23a3bc98512822a5af944e0 protocol: introduce wireproto.py - add a protocol-independent dispatcher - move most of the basic commands from sshserver to wireproto - dispatch through wireproto first diff -r 69248b5add46 -r 4530b3307fb9 mercurial/sshserver.py --- a/mercurial/sshserver.py Wed Jul 14 15:25:15 2010 -0500 +++ b/mercurial/sshserver.py Wed Jul 14 15:25:15 2010 -0500 @@ -8,7 +8,7 @@ from i18n import _ from node import bin, hex -import streamclone, util, hook, pushkey +import streamclone, util, hook, pushkey, wireproto import os, sys, tempfile, urllib, copy class sshserver(object): @@ -69,7 +69,7 @@ def serve_one(self): cmd = self.fin.readline()[:-1] - if cmd: + if cmd and not wireproto.dispatch(self.repo, self, cmd): impl = getattr(self, 'do_' + cmd, None) if impl: r = impl() @@ -78,29 +78,6 @@ else: self.respond("") return cmd != '' - def do_lookup(self): - key = self.getarg('key') - try: - r = hex(self.repo.lookup(key)) - success = 1 - except Exception, inst: - r = str(inst) - success = 0 - return "%s %s\n" % (success, r) - - def do_branchmap(self): - branchmap = self.repo.branchmap() - heads = [] - for branch, nodes in branchmap.iteritems(): - branchname = urllib.quote(branch) - branchnodes = [hex(node) for node in nodes] - heads.append('%s %s' % (branchname, ' '.join(branchnodes))) - return '\n'.join(heads) - - def do_heads(self): - h = self.repo.heads() - return " ".join(map(hex, h)) + "\n" - def do_hello(self): '''the hello command returns a set of lines describing various interesting things about the server, in an RFC822-like format. @@ -128,22 +105,6 @@ self.lock = None return "" - def do_branches(self): - nodes = self.getarg('nodes') - nodes = map(bin, nodes.split(" ")) - r = [] - for b in self.repo.branches(nodes): - r.append(" ".join(map(hex, b)) + "\n") - return "".join(r) - - def do_between(self): - pairs = self.getarg('pairs') - pairs = [map(bin, p.split("-")) for p in pairs.split(" ")] - r = [] - for b in self.repo.between(pairs): - r.append(" ".join(map(hex, b)) + "\n") - return "".join(r) - def do_changegroup(self): nodes = [] roots = self.getarg('roots') @@ -244,15 +205,3 @@ except streamclone.StreamException, inst: self.fout.write(str(inst)) self.fout.flush() - - def do_pushkey(self): - namespace, key, old, new = self.getargs('namespace key old new') - r = pushkey.push(self.repo, namespace, key, old, new) - return '%s\n' % int(r) - - def do_listkeys(self): - namespace = self.getarg('namespace') - d = pushkey.list(self.repo, namespace).items() - t = '\n'.join(['%s\t%s' % (k.encode('string-escape'), - v.encode('string-escape')) for k, v in d]) - return t diff -r 69248b5add46 -r 4530b3307fb9 mercurial/wireproto.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/wireproto.py Wed Jul 14 15:25:15 2010 -0500 @@ -0,0 +1,75 @@ +# wireproto.py - generic wire protocol support functions +# +# Copyright 2005-2010 Matt Mackall +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +from i18n import _ +from node import bin, hex +import urllib +import pushkey as pushkey_ + +def dispatch(repo, proto, command): + if command not in commands: + return False + func, spec = commands[command] + args = proto.getargs(spec) + proto.respond(func(repo, *args)) + return True + +def between(repo, pairs): + pairs = [map(bin, p.split("-")) for p in pairs.split(" ")] + r = [] + for b in repo.between(pairs): + r.append(" ".join(map(hex, b)) + "\n") + return "".join(r) + +def branchmap(repo): + branchmap = repo.branchmap() + heads = [] + for branch, nodes in branchmap.iteritems(): + branchname = urllib.quote(branch) + branchnodes = [hex(node) for node in nodes] + heads.append('%s %s' % (branchname, ' '.join(branchnodes))) + return '\n'.join(heads) + +def branches(repo, nodes): + nodes = map(bin, nodes.split(" ")) + r = [] + for b in repo.branches(nodes): + r.append(" ".join(map(hex, b)) + "\n") + return "".join(r) + +def heads(repo): + h = repo.heads() + return " ".join(map(hex, h)) + "\n" + +def listkeys(repo, namespace): + d = pushkey_.list(repo, namespace).items() + t = '\n'.join(['%s\t%s' % (k.encode('string-escape'), + v.encode('string-escape')) for k, v in d]) + return t + +def lookup(repo, key): + try: + r = hex(repo.lookup(key)) + success = 1 + except Exception, inst: + r = str(inst) + success = 0 + return "%s %s\n" % (success, r) + +def pushkey(repo, namespace, key, old, new): + r = pushkey_.push(repo, namespace, key, old, new) + return '%s\n' % int(r) + +commands = { + 'between': (between, 'pairs'), + 'branchmap': (branchmap, ''), + 'branches': (branches, 'nodes'), + 'heads': (heads, ''), + 'listkeys': (listkeys, 'namespace'), + 'lookup': (lookup, 'key'), + 'pushkey': (pushkey, 'namespace key old new'), +}