Show More
@@ -493,6 +493,15 b' class httpv2peer(object):' | |||||
493 | def _call(self, name, **args): |
|
493 | def _call(self, name, **args): | |
494 | """Call a wire protocol command with arguments.""" |
|
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 | # TODO permissions should come from capabilities results. |
|
505 | # TODO permissions should come from capabilities results. | |
497 | permission = wireproto.commandsv2[name].permission |
|
506 | permission = wireproto.commandsv2[name].permission | |
498 | if permission not in ('push', 'pull'): |
|
507 | if permission not in ('push', 'pull'): | |
@@ -507,12 +516,6 b' class httpv2peer(object):' | |||||
507 | url = '%s/api/%s/%s/%s' % (self.url, wireprotov2server.HTTPV2, |
|
516 | url = '%s/api/%s/%s/%s' % (self.url, wireprotov2server.HTTPV2, | |
508 | permission, name) |
|
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 | # TODO this should be part of a generic peer for the frame-based |
|
519 | # TODO this should be part of a generic peer for the frame-based | |
517 | # protocol. |
|
520 | # protocol. | |
518 | reactor = wireprotoframing.clientreactor(hasmultiplesend=False, |
|
521 | reactor = wireprotoframing.clientreactor(hasmultiplesend=False, |
@@ -1305,113 +1305,3 b' def unbundle(repo, proto, heads):' | |||||
1305 | bundler.newpart('error:pushraced', |
|
1305 | bundler.newpart('error:pushraced', | |
1306 | [('message', stringutil.forcebytestr(exc))]) |
|
1306 | [('message', stringutil.forcebytestr(exc))]) | |
1307 | return wireprototypes.streamreslegacy(gen=bundler.getchunks()) |
|
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 | 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, | |
@@ -362,3 +364,111 b' class httpv2protocolhandler(object):' | |||||
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) |
General Comments 0
You need to be logged in to leave comments.
Login now