##// END OF EJS Templates
httprepo: long arguments support (issue2126)...
httprepo: long arguments support (issue2126) Send the command arguments in the HTTP headers. The command is still part of the URL. If the server does not have the 'httpheader' capability, the client will send the command arguments in the URL as it did previously. Web servers typically allow more data to be placed within the headers than in the URL, so this approach will: - Avoid HTTP errors due to using a URL that is too large. - Allow Mercurial to implement a more efficient wire protocol. An alternate approach is to send the arguments as part of the request body. This approach has been rejected because it requires the use of POST requests, so it would break any existing configuration that relies on the request type for authentication or caching. Extensibility: - The header size is provided by the server, which makes it possible to introduce an hgrc setting for it. - The client ignores the capability value after the first comma, which allows more information to be included in the future.

File last commit:

r13721:3458c15a default
r14093:ce99d887 default
Show More
sshserver.py
144 lines | 4.0 KiB | text/x-python | PythonLexer
Vadim Gelfer
fix comment.
r2399 # sshserver.py - ssh protocol server support for mercurial
Vadim Gelfer
refactor ssh server.
r2396 #
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
Vadim Gelfer
update copyrights.
r2859 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
Vadim Gelfer
refactor ssh server.
r2396 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Vadim Gelfer
refactor ssh server.
r2396
Matt Mackall
bundle: encapsulate all bundle streams in unbundle class
r12337 import util, hook, wireproto, changegroup
Matt Mackall
ssh: drop some old imports
r11596 import os, sys
Vadim Gelfer
refactor ssh server.
r2396
class sshserver(object):
def __init__(self, ui, repo):
self.ui = ui
self.repo = repo
self.lock = None
self.fin = sys.stdin
self.fout = sys.stdout
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 hook.redirect(True)
Vadim Gelfer
refactor ssh server.
r2396 sys.stdout = sys.stderr
# Prevent insertion/deletion of CRs
util.set_binary(self.fin)
util.set_binary(self.fout)
Matt Mackall
protocol: add ssh getargs...
r11579 def getargs(self, args):
data = {}
keys = args.split()
for n in xrange(len(keys)):
argline = self.fin.readline()[:-1]
arg, l = argline.split()
if arg not in keys:
raise util.Abort("unexpected parameter %r" % arg)
if arg == '*':
star = {}
Peter Arrenbrecht
wireproto: fix handling of '*' args for HTTP and SSH
r13721 for k in xrange(int(l)):
argline = self.fin.readline()[:-1]
Matt Mackall
protocol: add ssh getargs...
r11579 arg, l = argline.split()
val = self.fin.read(int(l))
star[arg] = val
data['*'] = star
else:
Peter Arrenbrecht
wireproto: fix handling of '*' args for HTTP and SSH
r13721 val = self.fin.read(int(l))
Matt Mackall
protocol: add ssh getargs...
r11579 data[arg] = val
return [data[k] for k in keys]
def getarg(self, name):
return self.getargs(name)[0]
Vadim Gelfer
refactor ssh server.
r2396
Dirkjan Ochtman
protocol: shuffle server methods to group send methods
r11621 def getfile(self, fpout):
Dirkjan Ochtman
protocol: rename send methods to get grouping by prefix
r11622 self.sendresponse('')
Dirkjan Ochtman
protocol: shuffle server methods to group send methods
r11621 count = int(self.fin.readline())
while count:
fpout.write(self.fin.read(count))
count = int(self.fin.readline())
def redirect(self):
pass
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 def groupchunks(self, changegroup):
Matt Mackall
protocol: unify changegroup commands...
r11584 while True:
d = changegroup.read(4096)
if not d:
break
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 yield d
Matt Mackall
protocol: unify changegroup commands...
r11584
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 def sendresponse(self, v):
self.fout.write("%d\n" % len(v))
self.fout.write(v)
Matt Mackall
protocol: unify changegroup commands...
r11584 self.fout.flush()
Matt Mackall
protocol: unify stream_out command
r11585 def sendstream(self, source):
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 for chunk in source.gen:
Matt Mackall
protocol: unify stream_out command
r11585 self.fout.write(chunk)
self.fout.flush()
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 def sendpushresponse(self, rsp):
Dirkjan Ochtman
protocol: rename send methods to get grouping by prefix
r11622 self.sendresponse('')
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 self.sendresponse(str(rsp.res))
Matt Mackall
protocol: unify unbundle on the server side
r11593
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 def sendpusherror(self, rsp):
self.sendresponse(rsp.res)
Vadim Gelfer
refactor ssh server.
r2396 def serve_forever(self):
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 try:
Matt Mackall
many, many trivial check-code fixups
r10282 while self.serve_one():
pass
Ronny Pfannschmidt
switch lock releasing in the core from gc to explicit
r8109 finally:
if self.lock is not None:
self.lock.release()
Vadim Gelfer
refactor ssh server.
r2396 sys.exit(0)
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 handlers = {
str: sendresponse,
wireproto.streamres: sendstream,
wireproto.pushres: sendpushresponse,
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 wireproto.pusherr: sendpusherror,
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 }
Vadim Gelfer
refactor ssh server.
r2396 def serve_one(self):
cmd = self.fin.readline()[:-1]
Dirkjan Ochtman
protocol: command must be checked before passing in
r11618 if cmd and cmd in wireproto.commands:
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 rsp = wireproto.dispatch(self.repo, self, cmd)
self.handlers[rsp.__class__](self, rsp)
Dirkjan Ochtman
protocol: command must be checked before passing in
r11618 elif cmd:
Vadim Gelfer
refactor ssh server.
r2396 impl = getattr(self, 'do_' + cmd, None)
Matt Mackall
many, many trivial check-code fixups
r10282 if impl:
Matt Mackall
protocol: move most ssh responses to returns
r11580 r = impl()
if r is not None:
Dirkjan Ochtman
protocol: rename send methods to get grouping by prefix
r11622 self.sendresponse(r)
else: self.sendresponse("")
Vadim Gelfer
refactor ssh server.
r2396 return cmd != ''
def do_lock(self):
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 '''DEPRECATED - allowing remote client to lock repo is not safe'''
Vadim Gelfer
refactor ssh server.
r2396 self.lock = self.repo.lock()
Matt Mackall
protocol: move most ssh responses to returns
r11580 return ""
Vadim Gelfer
refactor ssh server.
r2396
def do_unlock(self):
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 '''DEPRECATED'''
Vadim Gelfer
refactor ssh server.
r2396 if self.lock:
self.lock.release()
self.lock = None
Matt Mackall
protocol: move most ssh responses to returns
r11580 return ""
Vadim Gelfer
refactor ssh server.
r2396
def do_addchangegroup(self):
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 '''DEPRECATED'''
Vadim Gelfer
refactor ssh server.
r2396 if not self.lock:
Dirkjan Ochtman
protocol: rename send methods to get grouping by prefix
r11622 self.sendresponse("not locked")
Vadim Gelfer
refactor ssh server.
r2396 return
Dirkjan Ochtman
protocol: rename send methods to get grouping by prefix
r11622 self.sendresponse("")
Matt Mackall
bundle: encapsulate all bundle streams in unbundle class
r12337 cg = changegroup.unbundle10(self.fin, "UN")
r = self.repo.addchangegroup(cg, 'serve', self._client(),
Matt Mackall
addchangegroup: pass in lock to release it before changegroup hook is called...
r11442 lock=self.lock)
Matt Mackall
protocol: move most ssh responses to returns
r11580 return str(r)
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439
Matt Mackall
protocol: unify unbundle on the server side
r11593 def _client(self):
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
return 'remote:ssh:' + client