625 """return a valid unbundler object for a given magicstring""" |
625 """return a valid unbundler object for a given magicstring""" |
626 if magicstring is None: |
626 if magicstring is None: |
627 magicstring = changegroup.readexactly(fp, 4) |
627 magicstring = changegroup.readexactly(fp, 4) |
628 magic, version = magicstring[0:2], magicstring[2:4] |
628 magic, version = magicstring[0:2], magicstring[2:4] |
629 if magic != 'HG': |
629 if magic != 'HG': |
630 raise util.Abort(_('not a Mercurial bundle')) |
630 raise error.Abort(_('not a Mercurial bundle')) |
631 unbundlerclass = formatmap.get(version) |
631 unbundlerclass = formatmap.get(version) |
632 if unbundlerclass is None: |
632 if unbundlerclass is None: |
633 raise util.Abort(_('unknown bundle version %s') % version) |
633 raise error.Abort(_('unknown bundle version %s') % version) |
634 unbundler = unbundlerclass(ui, fp) |
634 unbundler = unbundlerclass(ui, fp) |
635 indebug(ui, 'start processing of %s stream' % magicstring) |
635 indebug(ui, 'start processing of %s stream' % magicstring) |
636 return unbundler |
636 return unbundler |
637 |
637 |
638 class unbundle20(unpackermixin): |
638 class unbundle20(unpackermixin): |
1204 if self._pos != newpos: |
1204 if self._pos != newpos: |
1205 chunk, internaloffset = self._findchunk(newpos) |
1205 chunk, internaloffset = self._findchunk(newpos) |
1206 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk)) |
1206 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk)) |
1207 adjust = self.read(internaloffset) |
1207 adjust = self.read(internaloffset) |
1208 if len(adjust) != internaloffset: |
1208 if len(adjust) != internaloffset: |
1209 raise util.Abort(_('Seek failed\n')) |
1209 raise error.Abort(_('Seek failed\n')) |
1210 self._pos = newpos |
1210 self._pos = newpos |
1211 |
1211 |
1212 # These are only the static capabilities. |
1212 # These are only the static capabilities. |
1213 # Check the 'getrepocaps' function for the rest. |
1213 # Check the 'getrepocaps' function for the rest. |
1214 capabilities = {'HG20': (), |
1214 capabilities = {'HG20': (), |
1302 When multiple digest types are given, all of them are checked. |
1302 When multiple digest types are given, all of them are checked. |
1303 """ |
1303 """ |
1304 try: |
1304 try: |
1305 raw_url = inpart.params['url'] |
1305 raw_url = inpart.params['url'] |
1306 except KeyError: |
1306 except KeyError: |
1307 raise util.Abort(_('remote-changegroup: missing "%s" param') % 'url') |
1307 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'url') |
1308 parsed_url = util.url(raw_url) |
1308 parsed_url = util.url(raw_url) |
1309 if parsed_url.scheme not in capabilities['remote-changegroup']: |
1309 if parsed_url.scheme not in capabilities['remote-changegroup']: |
1310 raise util.Abort(_('remote-changegroup does not support %s urls') % |
1310 raise error.Abort(_('remote-changegroup does not support %s urls') % |
1311 parsed_url.scheme) |
1311 parsed_url.scheme) |
1312 |
1312 |
1313 try: |
1313 try: |
1314 size = int(inpart.params['size']) |
1314 size = int(inpart.params['size']) |
1315 except ValueError: |
1315 except ValueError: |
1316 raise util.Abort(_('remote-changegroup: invalid value for param "%s"') |
1316 raise error.Abort(_('remote-changegroup: invalid value for param "%s"') |
1317 % 'size') |
1317 % 'size') |
1318 except KeyError: |
1318 except KeyError: |
1319 raise util.Abort(_('remote-changegroup: missing "%s" param') % 'size') |
1319 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'size') |
1320 |
1320 |
1321 digests = {} |
1321 digests = {} |
1322 for typ in inpart.params.get('digests', '').split(): |
1322 for typ in inpart.params.get('digests', '').split(): |
1323 param = 'digest:%s' % typ |
1323 param = 'digest:%s' % typ |
1324 try: |
1324 try: |
1325 value = inpart.params[param] |
1325 value = inpart.params[param] |
1326 except KeyError: |
1326 except KeyError: |
1327 raise util.Abort(_('remote-changegroup: missing "%s" param') % |
1327 raise error.Abort(_('remote-changegroup: missing "%s" param') % |
1328 param) |
1328 param) |
1329 digests[typ] = value |
1329 digests[typ] = value |
1330 |
1330 |
1331 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests) |
1331 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests) |
1332 |
1332 |
1337 # for the whole processing scope. |
1337 # for the whole processing scope. |
1338 op.gettransaction() |
1338 op.gettransaction() |
1339 from . import exchange |
1339 from . import exchange |
1340 cg = exchange.readbundle(op.repo.ui, real_part, raw_url) |
1340 cg = exchange.readbundle(op.repo.ui, real_part, raw_url) |
1341 if not isinstance(cg, changegroup.cg1unpacker): |
1341 if not isinstance(cg, changegroup.cg1unpacker): |
1342 raise util.Abort(_('%s: not a bundle version 1.0') % |
1342 raise error.Abort(_('%s: not a bundle version 1.0') % |
1343 util.hidepassword(raw_url)) |
1343 util.hidepassword(raw_url)) |
1344 ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') |
1344 ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') |
1345 op.records.add('changegroup', {'return': ret}) |
1345 op.records.add('changegroup', {'return': ret}) |
1346 if op.reply is not None: |
1346 if op.reply is not None: |
1347 # This is definitely not the final form of this |
1347 # This is definitely not the final form of this |
1349 part = op.reply.newpart('reply:changegroup') |
1349 part = op.reply.newpart('reply:changegroup') |
1350 part.addparam('in-reply-to', str(inpart.id), mandatory=False) |
1350 part.addparam('in-reply-to', str(inpart.id), mandatory=False) |
1351 part.addparam('return', '%i' % ret, mandatory=False) |
1351 part.addparam('return', '%i' % ret, mandatory=False) |
1352 try: |
1352 try: |
1353 real_part.validate() |
1353 real_part.validate() |
1354 except util.Abort as e: |
1354 except error.Abort as e: |
1355 raise util.Abort(_('bundle at %s is corrupted:\n%s') % |
1355 raise error.Abort(_('bundle at %s is corrupted:\n%s') % |
1356 (util.hidepassword(raw_url), str(e))) |
1356 (util.hidepassword(raw_url), str(e))) |
1357 assert not inpart.read() |
1357 assert not inpart.read() |
1358 |
1358 |
1359 @parthandler('reply:changegroup', ('return', 'in-reply-to')) |
1359 @parthandler('reply:changegroup', ('return', 'in-reply-to')) |
1360 def handlereplychangegroup(op, inpart): |
1360 def handlereplychangegroup(op, inpart): |
1397 op.reply = bundle20(op.ui, caps) |
1397 op.reply = bundle20(op.ui, caps) |
1398 |
1398 |
1399 @parthandler('error:abort', ('message', 'hint')) |
1399 @parthandler('error:abort', ('message', 'hint')) |
1400 def handleerrorabort(op, inpart): |
1400 def handleerrorabort(op, inpart): |
1401 """Used to transmit abort error over the wire""" |
1401 """Used to transmit abort error over the wire""" |
1402 raise util.Abort(inpart.params['message'], hint=inpart.params.get('hint')) |
1402 raise error.Abort(inpart.params['message'], hint=inpart.params.get('hint')) |
1403 |
1403 |
1404 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret', |
1404 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret', |
1405 'in-reply-to')) |
1405 'in-reply-to')) |
1406 def handleerrorpushkey(op, inpart): |
1406 def handleerrorpushkey(op, inpart): |
1407 """Used to transmit failure of a mandatory pushkey over the wire""" |
1407 """Used to transmit failure of a mandatory pushkey over the wire""" |