comparison mercurial/wireprotov2server.py @ 37546:3a2367e6c6f2

wireproto: move version 2 command handlers to wireprotov2server This is relatively straightforward. As part of this, we introduced a local @wireprotocommand that wraps the main one and defines a v2 only policy by default. Because the hacky HTTPv2 peer isn't using capabilities response yet, we had to move some code around to force import of wireprotov2server so commands are registered. This is super hacky. But this code will go away once the HTTPv2 peer is using the capabilities response to derive permissions. Differential Revision: https://phab.mercurial-scm.org/D3231
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 09 Apr 2018 19:35:39 -0700
parents 93397c4633f6
children 734515aca84d
comparison
equal deleted inserted replaced
37545:93397c4633f6 37546:3a2367e6c6f2
14 ) 14 )
15 from .thirdparty.zope import ( 15 from .thirdparty.zope import (
16 interface as zi, 16 interface as zi,
17 ) 17 )
18 from . import ( 18 from . import (
19 encoding,
19 error, 20 error,
20 pycompat, 21 pycompat,
22 util,
21 wireproto, 23 wireproto,
22 wireprotoframing, 24 wireprotoframing,
23 wireprototypes, 25 wireprototypes,
24 ) 26 )
25 27
360 def addcapabilities(self, repo, caps): 362 def addcapabilities(self, repo, caps):
361 return caps 363 return caps
362 364
363 def checkperm(self, perm): 365 def checkperm(self, perm):
364 raise NotImplementedError 366 raise NotImplementedError
367
368 def _capabilitiesv2(repo, proto):
369 """Obtain the set of capabilities for version 2 transports.
370
371 These capabilities are distinct from the capabilities for version 1
372 transports.
373 """
374 compression = []
375 for engine in wireproto.supportedcompengines(repo.ui, util.SERVERROLE):
376 compression.append({
377 b'name': engine.wireprotosupport().name,
378 })
379
380 caps = {
381 'commands': {},
382 'compression': compression,
383 }
384
385 for command, entry in wireproto.commandsv2.items():
386 caps['commands'][command] = {
387 'args': entry.args,
388 'permissions': [entry.permission],
389 }
390
391 return proto.addcapabilities(repo, caps)
392
393 def wireprotocommand(*args, **kwargs):
394 def register(func):
395 return wireproto.wireprotocommand(
396 *args, transportpolicy=wireproto.POLICY_V2_ONLY, **kwargs)(func)
397
398 return register
399
400 @wireprotocommand('branchmap', permission='pull')
401 def branchmapv2(repo, proto):
402 branchmap = {encoding.fromlocal(k): v
403 for k, v in repo.branchmap().iteritems()}
404
405 return wireprototypes.cborresponse(branchmap)
406
407 @wireprotocommand('capabilities', permission='pull')
408 def capabilitiesv2(repo, proto):
409 caps = _capabilitiesv2(repo, proto)
410
411 return wireprototypes.cborresponse(caps)
412
413 @wireprotocommand('heads',
414 args={
415 'publiconly': False,
416 },
417 permission='pull')
418 def headsv2(repo, proto, publiconly=False):
419 if publiconly:
420 repo = repo.filtered('immutable')
421
422 return wireprototypes.cborresponse(repo.heads())
423
424 @wireprotocommand('known',
425 args={
426 'nodes': [b'deadbeef'],
427 },
428 permission='pull')
429 def knownv2(repo, proto, nodes=None):
430 nodes = nodes or []
431 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
432 return wireprototypes.cborresponse(result)
433
434 @wireprotocommand('listkeys',
435 args={
436 'namespace': b'ns',
437 },
438 permission='pull')
439 def listkeysv2(repo, proto, namespace=None):
440 keys = repo.listkeys(encoding.tolocal(namespace))
441 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
442 for k, v in keys.iteritems()}
443
444 return wireprototypes.cborresponse(keys)
445
446 @wireprotocommand('lookup',
447 args={
448 'key': b'foo',
449 },
450 permission='pull')
451 def lookupv2(repo, proto, key):
452 key = encoding.tolocal(key)
453
454 # TODO handle exception.
455 node = repo.lookup(key)
456
457 return wireprototypes.cborresponse(node)
458
459 @wireprotocommand('pushkey',
460 args={
461 'namespace': b'ns',
462 'key': b'key',
463 'old': b'old',
464 'new': b'new',
465 },
466 permission='push')
467 def pushkeyv2(repo, proto, namespace, key, old, new):
468 # TODO handle ui output redirection
469 r = repo.pushkey(encoding.tolocal(namespace),
470 encoding.tolocal(key),
471 encoding.tolocal(old),
472 encoding.tolocal(new))
473
474 return wireprototypes.cborresponse(r)