##// END OF EJS Templates
Take advantage of fstat calls clustering per directory if OS support it....
Take advantage of fstat calls clustering per directory if OS support it. util module implements two versions of statfiles function _statfiles calls lstat per file _statfiles_clustered takes advantage of optimizations in osutil.c, stats all files in directory at once when new directory is hit and caches the results util.statfiles dispatches to appropriate version during module loading The speedup on directory tree with 2k directories and 63k files is about factor of 1.8 (1.3s -> 0.8s for hg diff - hg startup overhead about .2s) At this point only Win32 now benefit from this patch. Rest of OSes use the non clustered implementation.

File last commit:

r7010:9141bebe default
r7118:619ebf82 default
Show More
httprepo.py
460 lines | 16.5 KiB | text/x-python | PythonLexer
mpm@selenic.com
Break apart hg.py...
r1089 # httprepo.py - HTTP repository proxy classes for mercurial
#
Vadim Gelfer
update copyrights.
r2859 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
mpm@selenic.com
Break apart hg.py...
r1089 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Joel Rosdahl
Expand import * to allow Pyflakes to find problems
r6211 from node import bin, hex
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Matt Mackall
fix-up references to repo.RepoError
r5176 import repo, os, urllib, urllib2, urlparse, zlib, util, httplib
Bryan O'Sullivan
Backed out changeset 4b81eecc8aa2
r6293 import errno, keepalive, socket, changegroup
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
httprepo: make "http://user:pass@host/" urls work
r2447 class passwordmgr(urllib2.HTTPPasswordMgrWithDefaultRealm):
Vadim Gelfer
prompt user for http authentication info...
r2281 def __init__(self, ui):
Vadim Gelfer
httprepo: make "http://user:pass@host/" urls work
r2447 urllib2.HTTPPasswordMgrWithDefaultRealm.__init__(self)
Vadim Gelfer
prompt user for http authentication info...
r2281 self.ui = ui
def find_user_password(self, realm, authuri):
Vadim Gelfer
httprepo: make "http://user:pass@host/" urls work
r2447 authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
Vadim Gelfer
prompt user for http authentication info...
r2281 self, realm, authuri)
Alexis S. L. Carvalho
Allow http://user@example.com URLs (i.e. without passwords)
r2556 user, passwd = authinfo
if user and passwd:
return (user, passwd)
Vadim Gelfer
prompt user for http authentication info...
r2281
Vadim Gelfer
httprepo: fix small bug in authentication.
r2446 if not self.ui.interactive:
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 raise util.Abort(_('http authorization required'))
Vadim Gelfer
prompt user for http authentication info...
r2281 self.ui.write(_("http authorization required\n"))
self.ui.status(_("realm: %s\n") % realm)
Alexis S. L. Carvalho
Allow http://user@example.com URLs (i.e. without passwords)
r2556 if user:
self.ui.status(_("user: %s\n") % user)
else:
user = self.ui.prompt(_("user:"), default=None)
if not passwd:
passwd = self.ui.getpass()
Vadim Gelfer
prompt user for http authentication info...
r2281
self.add_password(realm, authuri, user, passwd)
return (user, passwd)
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 def netlocsplit(netloc):
'''split [user[:passwd]@]host[:port] into 4-tuple.'''
a = netloc.find('@')
if a == -1:
user, passwd = None, None
else:
userpass, netloc = netloc[:a], netloc[a+1:]
c = userpass.find(':')
if c == -1:
user, passwd = urllib.unquote(userpass), None
else:
user = urllib.unquote(userpass[:c])
passwd = urllib.unquote(userpass[c+1:])
c = netloc.find(':')
if c == -1:
host, port = netloc, None
else:
host, port = netloc[:c], netloc[c+1:]
return host, port, user, passwd
def netlocunsplit(host, port, user=None, passwd=None):
'''turn host, port, user, passwd into [user[:passwd]@]host[:port].'''
if port:
hostport = host + ':' + port
else:
hostport = host
if user:
if passwd:
userpass = urllib.quote(user) + ':' + urllib.quote(passwd)
else:
userpass = urllib.quote(user)
return userpass + '@' + hostport
return hostport
Alexis S. L. Carvalho
Work around a urllib2 bug in Python < 2.4.2...
r4226 # work around a bug in Python < 2.4.2
# (it leaves a "\n" at the end of Proxy-authorization headers)
class request(urllib2.Request):
def add_header(self, key, val):
if key.lower() == 'proxy-authorization':
val = val.strip()
return urllib2.Request.add_header(self, key, val)
Benoit Boissinot
Subclass file with a __len__ method instead of setting Content-length...
r4025 class httpsendfile(file):
def __len__(self):
return os.fstat(self.fileno()).st_size
Vadim Gelfer
push over http: client support....
r2465
Benoit Boissinot
Subclass file with a __len__ method instead of setting Content-length...
r4025 def _gen_sendfile(connection):
def _sendfile(self, data):
# send a file
if isinstance(data, httpsendfile):
Vadim Gelfer
push over http: client support....
r2465 # if auth required, some data sent twice, so rewind here
data.seek(0)
for chunk in util.filechunkiter(data):
Benoit Boissinot
Subclass file with a __len__ method instead of setting Content-length...
r4025 connection.send(self, chunk)
else:
connection.send(self, data)
return _sendfile
class httpconnection(keepalive.HTTPConnection):
# must be able to send big bundle as stream.
send = _gen_sendfile(keepalive.HTTPConnection)
Vadim Gelfer
push over http: client support....
r2465
Alexis S. L. Carvalho
httprepo: use separate handlers for HTTP and HTTPS...
r5983 class httphandler(keepalive.HTTPHandler):
Vadim Gelfer
push over http: client support....
r2465 def http_open(self, req):
return self.do_open(httpconnection, req)
Alexis S. L. Carvalho
move __del__ from httprepository to basehttphandler...
r5982 def __del__(self):
self.close_all()
Alexis S. L. Carvalho
HTTPS: fix python2.3, persistent connections, don't explode if SSL is not available...
r2569 has_https = hasattr(urllib2, 'HTTPSHandler')
if has_https:
class httpsconnection(httplib.HTTPSConnection):
response_class = keepalive.HTTPResponse
# must be able to send big bundle as stream.
Benoit Boissinot
Subclass file with a __len__ method instead of setting Content-length...
r4025 send = _gen_sendfile(httplib.HTTPSConnection)
Alexis S. L. Carvalho
Fix push over https....
r2557
Alexis S. L. Carvalho
httprepo: use separate handlers for HTTP and HTTPS...
r5983 class httpshandler(keepalive.KeepAliveHandler, urllib2.HTTPSHandler):
Alexis S. L. Carvalho
HTTPS: fix python2.3, persistent connections, don't explode if SSL is not available...
r2569 def https_open(self, req):
return self.do_open(httpsconnection, req)
Alexis S. L. Carvalho
Fix push over https....
r2557
Alexis S. L. Carvalho
Work around urllib2 digest auth bug with Python < 2.5...
r4678 # In python < 2.5 AbstractDigestAuthHandler raises a ValueError if
# it doesn't know about the auth type requested. This can happen if
# somebody is using BasicAuth and types a bad password.
class httpdigestauthhandler(urllib2.HTTPDigestAuthHandler):
def http_error_auth_reqed(self, auth_header, host, req, headers):
try:
return urllib2.HTTPDigestAuthHandler.http_error_auth_reqed(
self, auth_header, host, req, headers)
except ValueError, inst:
arg = inst.args[0]
if arg.startswith("AbstractDigestAuthHandler doesn't know "):
return
raise
Matt Mackall
remove duplicate zgenerator in httprepo
r3661 def zgenerator(f):
zd = zlib.decompressobj()
try:
for chunk in util.filechunkiter(f):
yield zd.decompress(chunk)
except httplib.HTTPException, inst:
raise IOError(None, _('connection ended unexpectedly'))
yield zd.flush()
Alexis S. L. Carvalho
httprepo: quote the path part of the URL...
r5066 _safe = ('abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'0123456789' '_.-/')
_safeset = None
_hex = None
def quotepath(path):
'''quote the path part of a URL
This is similar to urllib.quote, but it also tries to avoid
quoting things twice (inspired by wget):
>>> quotepath('abc def')
'abc%20def'
>>> quotepath('abc%20def')
'abc%20def'
>>> quotepath('abc%20 def')
'abc%20%20def'
>>> quotepath('abc def%20')
'abc%20def%20'
>>> quotepath('abc def%2')
'abc%20def%252'
>>> quotepath('abc def%')
'abc%20def%25'
'''
global _safeset, _hex
if _safeset is None:
_safeset = util.set(_safe)
_hex = util.set('abcdefABCDEF0123456789')
l = list(path)
for i in xrange(len(l)):
c = l[i]
if c == '%' and i + 2 < len(l) and (l[i+1] in _hex and l[i+2] in _hex):
pass
elif c not in _safeset:
l[i] = '%%%02X' % ord(c)
return ''.join(l)
Matt Mackall
remoterepo: no longer needed...
r6313 class httprepository(repo.repository):
mpm@selenic.com
Break apart hg.py...
r1089 def __init__(self, ui, path):
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 self.path = path
Vadim Gelfer
http: query server for capabilities
r2442 self.caps = None
Andrei Vermel
Close keepalive connections to fix server traceback
r4132 self.handler = None
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
if query or frag:
raise util.Abort(_('unsupported URL component: "%s"') %
(query or frag))
Alexis S. L. Carvalho
httprepo: quote the path part of the URL...
r5066 if not urlpath:
urlpath = '/'
urlpath = quotepath(urlpath)
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 host, port, user, passwd = netlocsplit(netloc)
# urllib cannot handle URLs with embedded user or passwd
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
urlpath, '', ''))
mpm@selenic.com
Break apart hg.py...
r1089 self.ui = ui
Alexis S. L. Carvalho
httprepo: quote the path part of the URL...
r5066 self.ui.debug(_('using %s\n') % self._url)
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337
proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
Benoit Boissinot
fix warnings spotted by pychecker
r3131 # XXX proxyauthinfo = None
Alexis S. L. Carvalho
move __del__ from httprepository to basehttphandler...
r5982 handlers = [httphandler()]
Alexis S. L. Carvalho
httprepo: use separate handlers for HTTP and HTTPS...
r5983 if has_https:
handlers.append(httpshandler())
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337
if proxyurl:
# proxy can be proper url or host[:port]
if not (proxyurl.startswith('http:') or
proxyurl.startswith('https:')):
proxyurl = 'http://' + proxyurl + '/'
snpqf = urlparse.urlsplit(proxyurl)
proxyscheme, proxynetloc, proxypath, proxyquery, proxyfrag = snpqf
hpup = netlocsplit(proxynetloc)
proxyhost, proxyport, proxyuser, proxypasswd = hpup
if not proxyuser:
proxyuser = ui.config("http_proxy", "user")
proxypasswd = ui.config("http_proxy", "passwd")
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 # see if we should use a proxy for this url
no_list = [ "localhost", "127.0.0.1" ]
Thomas Arendsen Hein
Make "[web] allow_push, deny_push" and "[http_proxy] no" use ui.configlist.
r2501 no_list.extend([p.lower() for
p in ui.configlist("http_proxy", "no")])
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 no_list.extend([p.strip().lower() for
p in os.getenv("no_proxy", '').split(',')
if p.strip()])
# "http_proxy.always" config is for running tests on localhost
if (not ui.configbool("http_proxy", "always") and
host.lower() in no_list):
Sebastian Hauer
httprepo: ignore environment proxies when proxies are disabled
r5476 # avoid auto-detection of proxy settings by appending
# a ProxyHandler with no proxies defined.
handlers.append(urllib2.ProxyHandler({}))
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 ui.debug(_('disabling proxy for %s\n') % host)
else:
proxyurl = urlparse.urlunsplit((
proxyscheme, netlocunsplit(proxyhost, proxyport,
proxyuser, proxypasswd or ''),
proxypath, proxyquery, proxyfrag))
Alexis S. L. Carvalho
Use httpconnection even with proxies....
r3608 handlers.append(urllib2.ProxyHandler({scheme: proxyurl}))
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223 ui.debug(_('proxying through http://%s:%s\n') %
TK Soh
do not disclose proxy user and password in debug messages
r3170 (proxyhost, proxyport))
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 # urllib2 takes proxy values from the environment and those
# will take precedence if found, so drop them
mpm@selenic.com
Break apart hg.py...
r1089 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
try:
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if env in os.environ:
mpm@selenic.com
Break apart hg.py...
r1089 del os.environ[env]
except OSError:
pass
Vadim Gelfer
http: fix many problems with url parsing and auth. added proxy test....
r2337 passmgr = passwordmgr(ui)
if user:
Alexis S. L. Carvalho
Allow http://user@example.com URLs (i.e. without passwords)
r2556 ui.debug(_('http auth: user %s, password %s\n') %
(user, passwd and '*' * len(passwd) or 'not set'))
Alexis S. L. Carvalho
httprepo: give self._url and the netloc to the password manager...
r5526 netloc = host
if port:
netloc += ':' + port
# Python < 2.4.3 uses only the netloc to search for a password
passmgr.add_password(None, (self._url, netloc), user, passwd or '')
mpm@selenic.com
Break apart hg.py...
r1089
Alexis S. L. Carvalho
Use httpconnection even with proxies....
r3608 handlers.extend((urllib2.HTTPBasicAuthHandler(passmgr),
Alexis S. L. Carvalho
Work around urllib2 digest auth bug with Python < 2.5...
r4678 httpdigestauthhandler(passmgr)))
Alexis S. L. Carvalho
Use httpconnection even with proxies....
r3608 opener = urllib2.build_opener(*handlers)
Vadim Gelfer
prompt user for http authentication info...
r2281
Matt Mackall
Set the user agent for httprepo communication
r1359 # 1.0 here is the _protocol_ version
Bryan O'Sullivan
Backed out changeset 4b81eecc8aa2
r6293 opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
Dirkjan Ochtman
add an Accept header to the http client
r6787 opener.addheaders.append(('Accept', 'application/mercurial-0.1'))
mpm@selenic.com
Break apart hg.py...
r1089 urllib2.install_opener(opener)
Thomas Arendsen Hein
Removed trailing whitespace and tabs from python files
r4516
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def url(self):
return self.path
Vadim Gelfer
http: query server for capabilities
r2442 # look up capabilities only when needed
def get_caps(self):
if self.caps is None:
try:
Bryan O'Sullivan
Turn capabilities into a mutable set, instead of a fixed tuple.
r5258 self.caps = util.set(self.do_read('capabilities').split())
Matt Mackall
fix-up references to repo.RepoError
r5176 except repo.RepoError:
Bryan O'Sullivan
Turn capabilities into a mutable set, instead of a fixed tuple.
r5258 self.caps = util.set()
Vadim Gelfer
push over http: client support....
r2465 self.ui.debug(_('capabilities: %s\n') %
(' '.join(self.caps or ['none'])))
Vadim Gelfer
http: query server for capabilities
r2442 return self.caps
capabilities = property(get_caps)
Vadim Gelfer
make push over http print good error message.
r1870 def lock(self):
raise util.Abort(_('operation not supported over http'))
mpm@selenic.com
Break apart hg.py...
r1089 def do_cmd(self, cmd, **args):
Vadim Gelfer
push over http: client support....
r2465 data = args.pop('data', None)
headers = args.pop('headers', {})
Benoit Boissinot
i18n part2: use '_' for all strings who are part of the user interface
r1402 self.ui.debug(_("sending %s command\n") % cmd)
mpm@selenic.com
Break apart hg.py...
r1089 q = {"cmd": cmd}
q.update(args)
Benoit Boissinot
httprepo: record the url after a request, makes pull + redirect works...
r3562 qs = '?%s' % urllib.urlencode(q)
cu = "%s%s" % (self._url, qs)
Thomas Arendsen Hein
Catch urllib's HTTPException and give a meaningful error message to the user....
r2294 try:
Thomas Arendsen Hein
Turn bundle file into a string for http push, for urllib2 over proxies.
r3567 if data:
Alexis S. L. Carvalho
Push over HTTP: really tell the user the size of the bundle
r5333 self.ui.debug(_("sending %s bytes\n") % len(data))
Alexis S. L. Carvalho
Work around a urllib2 bug in Python < 2.4.2...
r4226 resp = urllib2.urlopen(request(cu, data, headers))
Vadim Gelfer
http client: better work with authorization errors, broken sockets.
r2467 except urllib2.HTTPError, inst:
if inst.code == 401:
raise util.Abort(_('authorization failed'))
raise
Thomas Arendsen Hein
Catch urllib's HTTPException and give a meaningful error message to the user....
r2294 except httplib.HTTPException, inst:
Vadim Gelfer
http: print better error if exception happens.
r2336 self.ui.debug(_('http error while sending %s command\n') % cmd)
self.ui.print_exc()
raise IOError(None, inst)
Thomas Arendsen Hein
Catch python2.3's IndexError with bogus http proxy settings. (issue203)
r3399 except IndexError:
# this only happens with Python 2.3, later versions raise URLError
raise util.Abort(_('http error, possibly caused by proxy setting'))
Benoit Boissinot
httprepo: record the url after a request, makes pull + redirect works...
r3562 # record the url we got redirected to
Thomas Arendsen Hein
Inform the user about the new URL when being redirected via http....
r3570 resp_url = resp.geturl()
if resp_url.endswith(qs):
resp_url = resp_url[:-len(qs)]
if self._url != resp_url:
self.ui.status(_('real URL is %s\n') % resp_url)
self._url = resp_url
Vadim Gelfer
http client: support persistent connections....
r2435 try:
proto = resp.getheader('content-type')
except AttributeError:
proto = resp.headers['content-type']
mpm@selenic.com
Break apart hg.py...
r1089
# accept old "text/plain" and "application/hg-changegroup" for now
Thomas Arendsen Hein
Cleanup of whitespace, indentation and line continuation.
r4633 if not (proto.startswith('application/mercurial-') or
proto.startswith('text/plain') or
proto.startswith('application/hg-changegroup')):
Thomas Arendsen Hein
Added full URL to debug output if something doesn't look like an http hg repo....
r4739 self.ui.debug(_("Requested URL: '%s'\n") % cu)
Matt Mackall
fix-up references to repo.RepoError
r5176 raise repo.RepoError(_("'%s' does not appear to be an hg repository")
Thomas Arendsen Hein
Cleanup of whitespace, indentation and line continuation.
r4633 % self._url)
mpm@selenic.com
Break apart hg.py...
r1089
Benoit Boissinot
fix handling of multiple Content-type headers...
r4012 if proto.startswith('application/mercurial-'):
try:
Thomas Arendsen Hein
Avoid float rounding errors when checking http protocol version.
r4356 version = proto.split('-', 1)[1]
version_info = tuple([int(n) for n in version.split('.')])
Benoit Boissinot
fix handling of multiple Content-type headers...
r4012 except ValueError:
Dirkjan Ochtman
send conservatively capitalized HTTP headers
r5930 raise repo.RepoError(_("'%s' sent a broken Content-Type "
Benoit Boissinot
fix handling of multiple Content-type headers...
r4012 "header (%s)") % (self._url, proto))
Thomas Arendsen Hein
Avoid float rounding errors when checking http protocol version.
r4356 if version_info > (0, 1):
Matt Mackall
fix-up references to repo.RepoError
r5176 raise repo.RepoError(_("'%s' uses newer protocol %s") %
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 (self._url, version))
mpm@selenic.com
Break apart hg.py...
r1089
return resp
Vadim Gelfer
http client: support persistent connections....
r2435 def do_read(self, cmd, **args):
fp = self.do_cmd(cmd, **args)
try:
return fp.read()
finally:
# if using keepalive, allow connection to be reused
fp.close()
Eric Hopper
Adding changegroupsubset and lookup to web protocol so pull -r and...
r3444 def lookup(self, key):
Bryan O'Sullivan
Push capability checking into protocol-level code.
r5259 self.requirecap('lookup', _('look up remote revision'))
Matt Mackall
httprepo: add support for passing lookup exception data
r3445 d = self.do_cmd("lookup", key = key).read()
success, data = d[:-1].split(' ', 1)
if int(success):
return bin(data)
Matt Mackall
fix-up references to repo.RepoError
r5176 raise repo.RepoError(data)
Eric Hopper
Adding changegroupsubset and lookup to web protocol so pull -r and...
r3444
mpm@selenic.com
Break apart hg.py...
r1089 def heads(self):
Vadim Gelfer
http client: support persistent connections....
r2435 d = self.do_read("heads")
mpm@selenic.com
Break apart hg.py...
r1089 try:
return map(bin, d[:-1].split(" "))
except:
Thomas Arendsen Hein
Use the new UnexpectedOutput exception in httprepo, too.
r3565 raise util.UnexpectedOutput(_("unexpected response:"), d)
mpm@selenic.com
Break apart hg.py...
r1089
def branches(self, nodes):
n = " ".join(map(hex, nodes))
Vadim Gelfer
http client: support persistent connections....
r2435 d = self.do_read("branches", nodes=n)
mpm@selenic.com
Break apart hg.py...
r1089 try:
br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
return br
except:
Thomas Arendsen Hein
Use the new UnexpectedOutput exception in httprepo, too.
r3565 raise util.UnexpectedOutput(_("unexpected response:"), d)
mpm@selenic.com
Break apart hg.py...
r1089
def between(self, pairs):
n = "\n".join(["-".join(map(hex, p)) for p in pairs])
Vadim Gelfer
http client: support persistent connections....
r2435 d = self.do_read("between", pairs=n)
mpm@selenic.com
Break apart hg.py...
r1089 try:
p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
return p
except:
Thomas Arendsen Hein
Use the new UnexpectedOutput exception in httprepo, too.
r3565 raise util.UnexpectedOutput(_("unexpected response:"), d)
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
add preoutgoing and outgoing hooks....
r1736 def changegroup(self, nodes, kind):
mpm@selenic.com
Break apart hg.py...
r1089 n = " ".join(map(hex, nodes))
f = self.do_cmd("changegroup", roots=n)
Matt Mackall
remove duplicate zgenerator in httprepo
r3661 return util.chunkbuffer(zgenerator(f))
Eric Hopper
Adding changegroupsubset and lookup to web protocol so pull -r and...
r3444
def changegroupsubset(self, bases, heads, source):
Bryan O'Sullivan
Push capability checking into protocol-level code.
r5259 self.requirecap('changegroupsubset', _('look up remote changes'))
Eric Hopper
Adding changegroupsubset and lookup to web protocol so pull -r and...
r3444 baselst = " ".join([hex(n) for n in bases])
headlst = " ".join([hex(n) for n in heads])
f = self.do_cmd("changegroupsubset", bases=baselst, heads=headlst)
Matt Mackall
remove duplicate zgenerator in httprepo
r3661 return util.chunkbuffer(zgenerator(f))
mpm@selenic.com
Break apart hg.py...
r1089
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 def unbundle(self, cg, heads, source):
Vadim Gelfer
push over http: client support....
r2465 # have to stream bundle to a temp file because we do not have
# http 1.1 chunked transfer.
Matt Mackall
unduplicate bundle writing code from httprepo
r3662 type = ""
types = self.capable('unbundle')
Alexis S. L. Carvalho
fix push over HTTP to older servers
r3703 # servers older than d1b16a746db6 will send 'unbundle' as a
# boolean capability
try:
types = types.split(',')
except AttributeError:
types = [""]
Matt Mackall
unduplicate bundle writing code from httprepo
r3662 if types:
Alexis S. L. Carvalho
fix push over HTTP to older servers
r3703 for x in types:
Matt Mackall
unduplicate bundle writing code from httprepo
r3662 if x in changegroup.bundletypes:
type = x
break
Thomas Arendsen Hein
Client support for hgweb unbundle with versions.
r3613
Matt Mackall
unduplicate bundle writing code from httprepo
r3662 tempname = changegroup.writebundle(cg, None, type)
Benoit Boissinot
Subclass file with a __len__ method instead of setting Content-length...
r4025 fp = httpsendfile(tempname, "rb")
Vadim Gelfer
push over http: client support....
r2465 try:
try:
Benoit Boissinot
enhance the error output in case of failure during http push
r7010 resp = self.do_read(
'unbundle', data=fp,
headers={'Content-Type': 'application/octet-stream'},
heads=' '.join(map(hex, heads)))
resp_code, output = resp.split('\n', 1)
Vadim Gelfer
http client: better work with authorization errors, broken sockets.
r2467 try:
Benoit Boissinot
enhance the error output in case of failure during http push
r7010 ret = int(resp_code)
except ValueError, err:
raise util.UnexpectedOutput(
_('push failed (unexpected response):'), resp)
self.ui.write(output)
return ret
Vadim Gelfer
http client: better work with authorization errors, broken sockets.
r2467 except socket.error, err:
if err[0] in (errno.ECONNRESET, errno.EPIPE):
Thomas Arendsen Hein
Never apply string formatting to generated errors with util.Abort....
r3072 raise util.Abort(_('push failed: %s') % err[1])
Vadim Gelfer
http client: better work with authorization errors, broken sockets.
r2467 raise util.Abort(err[1])
Vadim Gelfer
push over http: client support....
r2465 finally:
fp.close()
os.unlink(tempname)
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439
Vadim Gelfer
add support for streaming clone....
r2612 def stream_out(self):
return self.do_cmd('stream_out')
mpm@selenic.com
Break apart hg.py...
r1089 class httpsrepository(httprepository):
Alexis S. L. Carvalho
HTTPS: fix python2.3, persistent connections, don't explode if SSL is not available...
r2569 def __init__(self, ui, path):
if not has_https:
raise util.Abort(_('Python support for SSL and HTTPS '
'is not installed'))
httprepository.__init__(self, ui, path)
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740
def instance(ui, path, create):
if create:
raise util.Abort(_('cannot create new http repository'))
if path.startswith('https:'):
return httpsrepository(ui, path)
return httprepository(ui, path)