Mercurial > hg
comparison mercurial/wireprotov2server.py @ 37784:ee0d5e9d77b2
wireproto: move version 2 commands dict to wireprotov2server
This was the final piece of version 2 referenced in wireproto. The
break between server implementations is now much cleaner.
Differential Revision: https://phab.mercurial-scm.org/D3399
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 16 Apr 2018 22:10:02 -0700 |
parents | 9d818539abfa |
children | 856f381ad74b |
comparison
equal
deleted
inserted
replaced
37783:9d818539abfa | 37784:ee0d5e9d77b2 |
---|---|
19 encoding, | 19 encoding, |
20 error, | 20 error, |
21 pycompat, | 21 pycompat, |
22 streamclone, | 22 streamclone, |
23 util, | 23 util, |
24 wireproto, | |
25 wireprotoframing, | 24 wireprotoframing, |
26 wireprototypes, | 25 wireprototypes, |
27 ) | 26 ) |
28 | 27 |
29 FRAMINGTYPE = b'application/mercurial-exp-framing-0005' | 28 FRAMINGTYPE = b'application/mercurial-exp-framing-0005' |
30 | 29 |
31 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2 | 30 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2 |
31 | |
32 COMMANDS = wireprototypes.commanddict() | |
32 | 33 |
33 def handlehttpv2request(rctx, req, res, checkperm, urlparts): | 34 def handlehttpv2request(rctx, req, res, checkperm, urlparts): |
34 from .hgweb import common as hgwebcommon | 35 from .hgweb import common as hgwebcommon |
35 | 36 |
36 # URL space looks like: <permissions>/<command>, where <permission> can | 37 # URL space looks like: <permissions>/<command>, where <permission> can |
85 # Extra commands that we handle that aren't really wire protocol | 86 # Extra commands that we handle that aren't really wire protocol |
86 # commands. Think extra hard before making this hackery available to | 87 # commands. Think extra hard before making this hackery available to |
87 # extension. | 88 # extension. |
88 extracommands = {'multirequest'} | 89 extracommands = {'multirequest'} |
89 | 90 |
90 if command not in wireproto.commandsv2 and command not in extracommands: | 91 if command not in COMMANDS and command not in extracommands: |
91 res.status = b'404 Not Found' | 92 res.status = b'404 Not Found' |
92 res.headers[b'Content-Type'] = b'text/plain' | 93 res.headers[b'Content-Type'] = b'text/plain' |
93 res.setbodybytes(_('unknown wire protocol command: %s\n') % command) | 94 res.setbodybytes(_('unknown wire protocol command: %s\n') % command) |
94 return | 95 return |
95 | 96 |
96 repo = rctx.repo | 97 repo = rctx.repo |
97 ui = repo.ui | 98 ui = repo.ui |
98 | 99 |
99 proto = httpv2protocolhandler(req, ui) | 100 proto = httpv2protocolhandler(req, ui) |
100 | 101 |
101 if (not wireproto.commandsv2.commandavailable(command, proto) | 102 if (not COMMANDS.commandavailable(command, proto) |
102 and command not in extracommands): | 103 and command not in extracommands): |
103 res.status = b'404 Not Found' | 104 res.status = b'404 Not Found' |
104 res.headers[b'Content-Type'] = b'text/plain' | 105 res.headers[b'Content-Type'] = b'text/plain' |
105 res.setbodybytes(_('invalid wire protocol command: %s') % command) | 106 res.setbodybytes(_('invalid wire protocol command: %s') % command) |
106 return | 107 return |
252 # iff each command is the same. | 253 # iff each command is the same. |
253 | 254 |
254 proto = httpv2protocolhandler(req, ui, args=command['args']) | 255 proto = httpv2protocolhandler(req, ui, args=command['args']) |
255 | 256 |
256 if reqcommand == b'multirequest': | 257 if reqcommand == b'multirequest': |
257 if not wireproto.commandsv2.commandavailable(command['command'], proto): | 258 if not COMMANDS.commandavailable(command['command'], proto): |
258 # TODO proper error mechanism | 259 # TODO proper error mechanism |
259 res.status = b'200 OK' | 260 res.status = b'200 OK' |
260 res.headers[b'Content-Type'] = b'text/plain' | 261 res.headers[b'Content-Type'] = b'text/plain' |
261 res.setbodybytes(_('wire protocol command not available: %s') % | 262 res.setbodybytes(_('wire protocol command not available: %s') % |
262 command['command']) | 263 command['command']) |
263 return True | 264 return True |
264 | 265 |
265 # TODO don't use assert here, since it may be elided by -O. | 266 # TODO don't use assert here, since it may be elided by -O. |
266 assert authedperm in (b'ro', b'rw') | 267 assert authedperm in (b'ro', b'rw') |
267 wirecommand = wireproto.commandsv2[command['command']] | 268 wirecommand = COMMANDS[command['command']] |
268 assert wirecommand.permission in ('push', 'pull') | 269 assert wirecommand.permission in ('push', 'pull') |
269 | 270 |
270 if authedperm == b'ro' and wirecommand.permission != 'pull': | 271 if authedperm == b'ro' and wirecommand.permission != 'pull': |
271 # TODO proper error mechanism | 272 # TODO proper error mechanism |
272 res.status = b'403 Forbidden' | 273 res.status = b'403 Forbidden' |
332 return repo.filtered('served') | 333 return repo.filtered('served') |
333 | 334 |
334 def dispatch(repo, proto, command): | 335 def dispatch(repo, proto, command): |
335 repo = getdispatchrepo(repo, proto, command) | 336 repo = getdispatchrepo(repo, proto, command) |
336 | 337 |
337 func, spec = wireproto.commandsv2[command] | 338 func, spec = COMMANDS[command] |
338 args = proto.getargs(spec) | 339 args = proto.getargs(spec) |
339 | 340 |
340 return func(repo, proto, **args) | 341 return func(repo, proto, **args) |
341 | 342 |
342 @zi.implementer(wireprototypes.baseprotocolhandler) | 343 @zi.implementer(wireprototypes.baseprotocolhandler) |
402 'commands': {}, | 403 'commands': {}, |
403 'compression': compression, | 404 'compression': compression, |
404 'framingmediatypes': [FRAMINGTYPE], | 405 'framingmediatypes': [FRAMINGTYPE], |
405 } | 406 } |
406 | 407 |
407 for command, entry in wireproto.commandsv2.items(): | 408 for command, entry in COMMANDS.items(): |
408 caps['commands'][command] = { | 409 caps['commands'][command] = { |
409 'args': entry.args, | 410 'args': entry.args, |
410 'permissions': [entry.permission], | 411 'permissions': [entry.permission], |
411 } | 412 } |
412 | 413 |
443 if not isinstance(args, dict): | 444 if not isinstance(args, dict): |
444 raise error.ProgrammingError('arguments for version 2 commands ' | 445 raise error.ProgrammingError('arguments for version 2 commands ' |
445 'must be declared as dicts') | 446 'must be declared as dicts') |
446 | 447 |
447 def register(func): | 448 def register(func): |
448 if name in wireproto.commandsv2: | 449 if name in COMMANDS: |
449 raise error.ProgrammingError('%s command already registered ' | 450 raise error.ProgrammingError('%s command already registered ' |
450 'for version 2' % name) | 451 'for version 2' % name) |
451 | 452 |
452 wireproto.commandsv2[name] = wireprototypes.commandentry( | 453 COMMANDS[name] = wireprototypes.commandentry( |
453 func, args=args, transports=transports, permission=permission) | 454 func, args=args, transports=transports, permission=permission) |
454 | 455 |
455 return func | 456 return func |
456 | 457 |
457 return register | 458 return register |