Show More
@@ -409,6 +409,56 b' class sshv1protocolhandler(baseprotocolh' | |||
|
409 | 409 | client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] |
|
410 | 410 | return 'remote:ssh:' + client |
|
411 | 411 | |
|
412 | def _runsshserver(ui, repo, fin, fout): | |
|
413 | state = 'protov1-serving' | |
|
414 | proto = sshv1protocolhandler(ui, fin, fout) | |
|
415 | ||
|
416 | while True: | |
|
417 | if state == 'protov1-serving': | |
|
418 | # Commands are issued on new lines. | |
|
419 | request = fin.readline()[:-1] | |
|
420 | ||
|
421 | # Empty lines signal to terminate the connection. | |
|
422 | if not request: | |
|
423 | state = 'shutdown' | |
|
424 | continue | |
|
425 | ||
|
426 | available = wireproto.commands.commandavailable(request, proto) | |
|
427 | ||
|
428 | # This command isn't available. Send an empty response and go | |
|
429 | # back to waiting for a new command. | |
|
430 | if not available: | |
|
431 | _sshv1respondbytes(fout, b'') | |
|
432 | continue | |
|
433 | ||
|
434 | rsp = wireproto.dispatch(repo, proto, request) | |
|
435 | ||
|
436 | if isinstance(rsp, bytes): | |
|
437 | _sshv1respondbytes(fout, rsp) | |
|
438 | elif isinstance(rsp, wireprototypes.bytesresponse): | |
|
439 | _sshv1respondbytes(fout, rsp.data) | |
|
440 | elif isinstance(rsp, wireprototypes.streamres): | |
|
441 | _sshv1respondstream(fout, rsp) | |
|
442 | elif isinstance(rsp, wireprototypes.streamreslegacy): | |
|
443 | _sshv1respondstream(fout, rsp) | |
|
444 | elif isinstance(rsp, wireprototypes.pushres): | |
|
445 | _sshv1respondbytes(fout, b'') | |
|
446 | _sshv1respondbytes(fout, b'%d' % rsp.res) | |
|
447 | elif isinstance(rsp, wireprototypes.pusherr): | |
|
448 | _sshv1respondbytes(fout, rsp.res) | |
|
449 | elif isinstance(rsp, wireprototypes.ooberror): | |
|
450 | _sshv1respondooberror(fout, ui.ferr, rsp.message) | |
|
451 | else: | |
|
452 | raise error.ProgrammingError('unhandled response type from ' | |
|
453 | 'wire protocol command: %s' % rsp) | |
|
454 | ||
|
455 | elif state == 'shutdown': | |
|
456 | break | |
|
457 | ||
|
458 | else: | |
|
459 | raise error.ProgrammingError('unhandled ssh server state: %s' % | |
|
460 | state) | |
|
461 | ||
|
412 | 462 | class sshserver(object): |
|
413 | 463 | def __init__(self, ui, repo): |
|
414 | 464 | self._ui = ui |
@@ -423,36 +473,6 b' class sshserver(object):' | |||
|
423 | 473 | util.setbinary(self._fin) |
|
424 | 474 | util.setbinary(self._fout) |
|
425 | 475 | |
|
426 | self._proto = sshv1protocolhandler(self._ui, self._fin, self._fout) | |
|
427 | ||
|
428 | 476 | def serve_forever(self): |
|
429 | while self.serve_one(): | |
|
430 | pass | |
|
477 | _runsshserver(self._ui, self._repo, self._fin, self._fout) | |
|
431 | 478 | sys.exit(0) |
|
432 | ||
|
433 | def serve_one(self): | |
|
434 | cmd = self._fin.readline()[:-1] | |
|
435 | if cmd and wireproto.commands.commandavailable(cmd, self._proto): | |
|
436 | rsp = wireproto.dispatch(self._repo, self._proto, cmd) | |
|
437 | ||
|
438 | if isinstance(rsp, bytes): | |
|
439 | _sshv1respondbytes(self._fout, rsp) | |
|
440 | elif isinstance(rsp, wireprototypes.bytesresponse): | |
|
441 | _sshv1respondbytes(self._fout, rsp.data) | |
|
442 | elif isinstance(rsp, wireprototypes.streamres): | |
|
443 | _sshv1respondstream(self._fout, rsp) | |
|
444 | elif isinstance(rsp, wireprototypes.streamreslegacy): | |
|
445 | _sshv1respondstream(self._fout, rsp) | |
|
446 | elif isinstance(rsp, wireprototypes.pushres): | |
|
447 | _sshv1respondbytes(self._fout, b'') | |
|
448 | _sshv1respondbytes(self._fout, b'%d' % rsp.res) | |
|
449 | elif isinstance(rsp, wireprototypes.pusherr): | |
|
450 | _sshv1respondbytes(self._fout, rsp.res) | |
|
451 | elif isinstance(rsp, wireprototypes.ooberror): | |
|
452 | _sshv1respondooberror(self._fout, self._ui.ferr, rsp.message) | |
|
453 | else: | |
|
454 | raise error.ProgrammingError('unhandled response type from ' | |
|
455 | 'wire protocol command: %s' % rsp) | |
|
456 | elif cmd: | |
|
457 | _sshv1respondbytes(self._fout, b'') | |
|
458 | return cmd != '' |
@@ -48,7 +48,9 b' class prehelloserver(wireprotoserver.ssh' | |||
|
48 | 48 | wireprotoserver._sshv1respondbytes(self._fout, b'') |
|
49 | 49 | l = self._fin.readline() |
|
50 | 50 | assert l == b'between\n' |
|
51 | rsp = wireproto.dispatch(self._repo, self._proto, b'between') | |
|
51 | proto = wireprotoserver.sshv1protocolhandler(self._ui, self._fin, | |
|
52 | self._fout) | |
|
53 | rsp = wireproto.dispatch(self._repo, proto, b'between') | |
|
52 | 54 | wireprotoserver._sshv1respondbytes(self._fout, rsp.data) |
|
53 | 55 | |
|
54 | 56 | super(prehelloserver, self).serve_forever() |
@@ -72,8 +74,10 b' class upgradev2server(wireprotoserver.ss' | |||
|
72 | 74 | self._fin.read(81) |
|
73 | 75 | |
|
74 | 76 | # Send the upgrade response. |
|
77 | proto = wireprotoserver.sshv1protocolhandler(self._ui, self._fin, | |
|
78 | self._fout) | |
|
75 | 79 | self._fout.write(b'upgraded %s %s\n' % (token, name)) |
|
76 |
servercaps = wireproto.capabilities(self._repo, |
|
|
80 | servercaps = wireproto.capabilities(self._repo, proto) | |
|
77 | 81 | rsp = b'capabilities: %s' % servercaps.data |
|
78 | 82 | self._fout.write(b'%d\n' % len(rsp)) |
|
79 | 83 | self._fout.write(rsp) |
@@ -23,8 +23,11 b' class SSHServerGetArgsTests(unittest.Tes' | |||
|
23 | 23 | |
|
24 | 24 | def assertparse(self, cmd, input, expected): |
|
25 | 25 | server = mockserver(input) |
|
26 | proto = wireprotoserver.sshv1protocolhandler(server._ui, | |
|
27 | server._fin, | |
|
28 | server._fout) | |
|
26 | 29 | _func, spec = wireproto.commands[cmd] |
|
27 |
self.assertEqual( |
|
|
30 | self.assertEqual(proto.getargs(spec), expected) | |
|
28 | 31 | |
|
29 | 32 | def mockserver(inbytes): |
|
30 | 33 | ui = mockui(inbytes) |
General Comments 0
You need to be logged in to leave comments.
Login now