Show More
@@ -493,6 +493,15 b' class httpv2peer(object):' | |||
|
493 | 493 | def _call(self, name, **args): |
|
494 | 494 | """Call a wire protocol command with arguments.""" |
|
495 | 495 | |
|
496 | # Having this early has a side-effect of importing wireprotov2server, | |
|
497 | # which has the side-effect of ensuring commands are registered. | |
|
498 | ||
|
499 | # TODO modify user-agent to reflect v2. | |
|
500 | headers = { | |
|
501 | r'Accept': wireprotov2server.FRAMINGTYPE, | |
|
502 | r'Content-Type': wireprotov2server.FRAMINGTYPE, | |
|
503 | } | |
|
504 | ||
|
496 | 505 | # TODO permissions should come from capabilities results. |
|
497 | 506 | permission = wireproto.commandsv2[name].permission |
|
498 | 507 | if permission not in ('push', 'pull'): |
@@ -507,12 +516,6 b' class httpv2peer(object):' | |||
|
507 | 516 | url = '%s/api/%s/%s/%s' % (self.url, wireprotov2server.HTTPV2, |
|
508 | 517 | permission, name) |
|
509 | 518 | |
|
510 | # TODO modify user-agent to reflect v2. | |
|
511 | headers = { | |
|
512 | r'Accept': wireprotov2server.FRAMINGTYPE, | |
|
513 | r'Content-Type': wireprotov2server.FRAMINGTYPE, | |
|
514 | } | |
|
515 | ||
|
516 | 519 | # TODO this should be part of a generic peer for the frame-based |
|
517 | 520 | # protocol. |
|
518 | 521 | reactor = wireprotoframing.clientreactor(hasmultiplesend=False, |
@@ -1305,113 +1305,3 b' def unbundle(repo, proto, heads):' | |||
|
1305 | 1305 | bundler.newpart('error:pushraced', |
|
1306 | 1306 | [('message', stringutil.forcebytestr(exc))]) |
|
1307 | 1307 | return wireprototypes.streamreslegacy(gen=bundler.getchunks()) |
|
1308 | ||
|
1309 | # Wire protocol version 2 commands only past this point. | |
|
1310 | ||
|
1311 | def _capabilitiesv2(repo, proto): | |
|
1312 | """Obtain the set of capabilities for version 2 transports. | |
|
1313 | ||
|
1314 | These capabilities are distinct from the capabilities for version 1 | |
|
1315 | transports. | |
|
1316 | """ | |
|
1317 | compression = [] | |
|
1318 | for engine in supportedcompengines(repo.ui, util.SERVERROLE): | |
|
1319 | compression.append({ | |
|
1320 | b'name': engine.wireprotosupport().name, | |
|
1321 | }) | |
|
1322 | ||
|
1323 | caps = { | |
|
1324 | 'commands': {}, | |
|
1325 | 'compression': compression, | |
|
1326 | } | |
|
1327 | ||
|
1328 | for command, entry in commandsv2.items(): | |
|
1329 | caps['commands'][command] = { | |
|
1330 | 'args': entry.args, | |
|
1331 | 'permissions': [entry.permission], | |
|
1332 | } | |
|
1333 | ||
|
1334 | return proto.addcapabilities(repo, caps) | |
|
1335 | ||
|
1336 | @wireprotocommand('branchmap', permission='pull', | |
|
1337 | transportpolicy=POLICY_V2_ONLY) | |
|
1338 | def branchmapv2(repo, proto): | |
|
1339 | branchmap = {encoding.fromlocal(k): v | |
|
1340 | for k, v in repo.branchmap().iteritems()} | |
|
1341 | ||
|
1342 | return wireprototypes.cborresponse(branchmap) | |
|
1343 | ||
|
1344 | @wireprotocommand('capabilities', permission='pull', | |
|
1345 | transportpolicy=POLICY_V2_ONLY) | |
|
1346 | def capabilitiesv2(repo, proto): | |
|
1347 | caps = _capabilitiesv2(repo, proto) | |
|
1348 | ||
|
1349 | return wireprototypes.cborresponse(caps) | |
|
1350 | ||
|
1351 | @wireprotocommand('heads', | |
|
1352 | args={ | |
|
1353 | 'publiconly': False, | |
|
1354 | }, | |
|
1355 | permission='pull', | |
|
1356 | transportpolicy=POLICY_V2_ONLY) | |
|
1357 | def headsv2(repo, proto, publiconly=False): | |
|
1358 | if publiconly: | |
|
1359 | repo = repo.filtered('immutable') | |
|
1360 | ||
|
1361 | return wireprototypes.cborresponse(repo.heads()) | |
|
1362 | ||
|
1363 | @wireprotocommand('known', | |
|
1364 | args={ | |
|
1365 | 'nodes': [b'deadbeef'], | |
|
1366 | }, | |
|
1367 | permission='pull', | |
|
1368 | transportpolicy=POLICY_V2_ONLY) | |
|
1369 | def knownv2(repo, proto, nodes=None): | |
|
1370 | nodes = nodes or [] | |
|
1371 | result = b''.join(b'1' if n else b'0' for n in repo.known(nodes)) | |
|
1372 | return wireprototypes.cborresponse(result) | |
|
1373 | ||
|
1374 | @wireprotocommand('listkeys', | |
|
1375 | args={ | |
|
1376 | 'namespace': b'ns', | |
|
1377 | }, | |
|
1378 | permission='pull', | |
|
1379 | transportpolicy=POLICY_V2_ONLY) | |
|
1380 | def listkeysv2(repo, proto, namespace=None): | |
|
1381 | keys = repo.listkeys(encoding.tolocal(namespace)) | |
|
1382 | keys = {encoding.fromlocal(k): encoding.fromlocal(v) | |
|
1383 | for k, v in keys.iteritems()} | |
|
1384 | ||
|
1385 | return wireprototypes.cborresponse(keys) | |
|
1386 | ||
|
1387 | @wireprotocommand('lookup', | |
|
1388 | args={ | |
|
1389 | 'key': b'foo', | |
|
1390 | }, | |
|
1391 | permission='pull', | |
|
1392 | transportpolicy=POLICY_V2_ONLY) | |
|
1393 | def lookupv2(repo, proto, key): | |
|
1394 | key = encoding.tolocal(key) | |
|
1395 | ||
|
1396 | # TODO handle exception. | |
|
1397 | node = repo.lookup(key) | |
|
1398 | ||
|
1399 | return wireprototypes.cborresponse(node) | |
|
1400 | ||
|
1401 | @wireprotocommand('pushkey', | |
|
1402 | args={ | |
|
1403 | 'namespace': b'ns', | |
|
1404 | 'key': b'key', | |
|
1405 | 'old': b'old', | |
|
1406 | 'new': b'new', | |
|
1407 | }, | |
|
1408 | permission='push', | |
|
1409 | transportpolicy=POLICY_V2_ONLY) | |
|
1410 | def pushkeyv2(repo, proto, namespace, key, old, new): | |
|
1411 | # TODO handle ui output redirection | |
|
1412 | r = repo.pushkey(encoding.tolocal(namespace), | |
|
1413 | encoding.tolocal(key), | |
|
1414 | encoding.tolocal(old), | |
|
1415 | encoding.tolocal(new)) | |
|
1416 | ||
|
1417 | return wireprototypes.cborresponse(r) |
@@ -16,8 +16,10 b' from .thirdparty.zope import (' | |||
|
16 | 16 | interface as zi, |
|
17 | 17 | ) |
|
18 | 18 | from . import ( |
|
19 | encoding, | |
|
19 | 20 | error, |
|
20 | 21 | pycompat, |
|
22 | util, | |
|
21 | 23 | wireproto, |
|
22 | 24 | wireprotoframing, |
|
23 | 25 | wireprototypes, |
@@ -362,3 +364,111 b' class httpv2protocolhandler(object):' | |||
|
362 | 364 | |
|
363 | 365 | def checkperm(self, perm): |
|
364 | 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) |
General Comments 0
You need to be logged in to leave comments.
Login now