This matches what we did for the SSH protocol handler in
ac33dc94e1d5.
.. api::
HTTP protocol handlers now advertises its internal name as ``http-v1`` instead of ``http``.
This matches what we did for the SSH protocol handler in
ac33dc94e1d5.
.. api::
HTTP protocol handlers now advertises its internal name as ``http-v1`` instead of ``http``.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
# otherwise, add 'streamreqs' detailing our local revlog format | # otherwise, add 'streamreqs' detailing our local revlog format | ||||
else: | else: | ||||
caps.append('streamreqs=%s' % ','.join(sorted(requiredformats))) | caps.append('streamreqs=%s' % ','.join(sorted(requiredformats))) | ||||
if repo.ui.configbool('experimental', 'bundle2-advertise'): | if repo.ui.configbool('experimental', 'bundle2-advertise'): | ||||
capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server')) | capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo, role='server')) | ||||
caps.append('bundle2=' + urlreq.quote(capsblob)) | caps.append('bundle2=' + urlreq.quote(capsblob)) | ||||
caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority)) | caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority)) | ||||
if proto.name == 'http': | if proto.name == 'http-v1': | ||||
caps.append('httpheader=%d' % | caps.append('httpheader=%d' % | ||||
repo.ui.configint('server', 'maxhttpheaderlen')) | repo.ui.configint('server', 'maxhttpheaderlen')) | ||||
if repo.ui.configbool('experimental', 'httppostargs'): | if repo.ui.configbool('experimental', 'httppostargs'): | ||||
caps.append('httppostargs') | caps.append('httppostargs') | ||||
# FUTURE advertise 0.2rx once support is implemented | # FUTURE advertise 0.2rx once support is implemented | ||||
# FUTURE advertise minrx and mintx after consulting config option | # FUTURE advertise minrx and mintx after consulting config option | ||||
caps.append('httpmediatype=0.1rx,0.1tx,0.2tx') | caps.append('httpmediatype=0.1rx,0.1tx,0.2tx') | ||||
else: | else: | ||||
opts[k] = bool(v) | opts[k] = bool(v) | ||||
elif keytype != 'plain': | elif keytype != 'plain': | ||||
raise KeyError('unknown getbundle option type %s' | raise KeyError('unknown getbundle option type %s' | ||||
% keytype) | % keytype) | ||||
if not bundle1allowed(repo, 'pull'): | if not bundle1allowed(repo, 'pull'): | ||||
if not exchange.bundle2requested(opts.get('bundlecaps')): | if not exchange.bundle2requested(opts.get('bundlecaps')): | ||||
if proto.name == 'http': | if proto.name == 'http-v1': | ||||
return ooberror(bundle2required) | return ooberror(bundle2required) | ||||
raise error.Abort(bundle2requiredmain, | raise error.Abort(bundle2requiredmain, | ||||
hint=bundle2requiredhint) | hint=bundle2requiredhint) | ||||
prefercompressed = True | prefercompressed = True | ||||
try: | try: | ||||
if repo.ui.configbool('server', 'disablefullbundle'): | if repo.ui.configbool('server', 'disablefullbundle'): | ||||
hint=_('remove --pull if specified or upgrade Mercurial')) | hint=_('remove --pull if specified or upgrade Mercurial')) | ||||
info, chunks = exchange.getbundlechunks(repo, 'serve', | info, chunks = exchange.getbundlechunks(repo, 'serve', | ||||
**pycompat.strkwargs(opts)) | **pycompat.strkwargs(opts)) | ||||
prefercompressed = info.get('prefercompressed', True) | prefercompressed = info.get('prefercompressed', True) | ||||
except error.Abort as exc: | except error.Abort as exc: | ||||
# cleanly forward Abort error to the client | # cleanly forward Abort error to the client | ||||
if not exchange.bundle2requested(opts.get('bundlecaps')): | if not exchange.bundle2requested(opts.get('bundlecaps')): | ||||
if proto.name == 'http': | if proto.name == 'http-v1': | ||||
return ooberror(str(exc) + '\n') | return ooberror(str(exc) + '\n') | ||||
raise # cannot do better for bundle1 + ssh | raise # cannot do better for bundle1 + ssh | ||||
# bundle2 request expect a bundle2 reply | # bundle2 request expect a bundle2 reply | ||||
bundler = bundle2.bundle20(repo.ui) | bundler = bundle2.bundle20(repo.ui) | ||||
manargs = [('message', str(exc))] | manargs = [('message', str(exc))] | ||||
advargs = [] | advargs = [] | ||||
if exc.hint is not None: | if exc.hint is not None: | ||||
advargs.append(('hint', exc.hint)) | advargs.append(('hint', exc.hint)) | ||||
fp = os.fdopen(fd, pycompat.sysstr('wb+')) | fp = os.fdopen(fd, pycompat.sysstr('wb+')) | ||||
r = 0 | r = 0 | ||||
try: | try: | ||||
proto.forwardpayload(fp) | proto.forwardpayload(fp) | ||||
fp.seek(0) | fp.seek(0) | ||||
gen = exchange.readbundle(repo.ui, fp, None) | gen = exchange.readbundle(repo.ui, fp, None) | ||||
if (isinstance(gen, changegroupmod.cg1unpacker) | if (isinstance(gen, changegroupmod.cg1unpacker) | ||||
and not bundle1allowed(repo, 'push')): | and not bundle1allowed(repo, 'push')): | ||||
if proto.name == 'http': | if proto.name == 'http-v1': | ||||
# need to special case http because stderr do not get to | # need to special case http because stderr do not get to | ||||
# the http client on failed push so we need to abuse | # the http client on failed push so we need to abuse | ||||
# some other error type to make sure the message get to | # some other error type to make sure the message get to | ||||
# the user. | # the user. | ||||
return ooberror(bundle2required) | return ooberror(bundle2required) | ||||
raise error.Abort(bundle2requiredmain, | raise error.Abort(bundle2requiredmain, | ||||
hint=bundle2requiredhint) | hint=bundle2requiredhint) | ||||
class httpv1protocolhandler(baseprotocolhandler): | class httpv1protocolhandler(baseprotocolhandler): | ||||
def __init__(self, req, ui): | def __init__(self, req, ui): | ||||
self._req = req | self._req = req | ||||
self._ui = ui | self._ui = ui | ||||
@property | @property | ||||
def name(self): | def name(self): | ||||
return 'http' | return 'http-v1' | ||||
def getargs(self, args): | def getargs(self, args): | ||||
knownargs = self._args() | knownargs = self._args() | ||||
data = {} | data = {} | ||||
keys = args.split() | keys = args.split() | ||||
for k in keys: | for k in keys: | ||||
if k == '*': | if k == '*': | ||||
star = {} | star = {} |