Show More
@@ -409,6 +409,56 b' class sshv1protocolhandler(baseprotocolh' | |||||
409 | client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] |
|
409 | client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] | |
410 | return 'remote:ssh:' + client |
|
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 | class sshserver(object): |
|
462 | class sshserver(object): | |
413 | def __init__(self, ui, repo): |
|
463 | def __init__(self, ui, repo): | |
414 | self._ui = ui |
|
464 | self._ui = ui | |
@@ -423,36 +473,6 b' class sshserver(object):' | |||||
423 | util.setbinary(self._fin) |
|
473 | util.setbinary(self._fin) | |
424 | util.setbinary(self._fout) |
|
474 | util.setbinary(self._fout) | |
425 |
|
475 | |||
426 | self._proto = sshv1protocolhandler(self._ui, self._fin, self._fout) |
|
|||
427 |
|
||||
428 | def serve_forever(self): |
|
476 | def serve_forever(self): | |
429 | while self.serve_one(): |
|
477 | _runsshserver(self._ui, self._repo, self._fin, self._fout) | |
430 | pass |
|
|||
431 | sys.exit(0) |
|
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 | wireprotoserver._sshv1respondbytes(self._fout, b'') |
|
48 | wireprotoserver._sshv1respondbytes(self._fout, b'') | |
49 | l = self._fin.readline() |
|
49 | l = self._fin.readline() | |
50 | assert l == b'between\n' |
|
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 | wireprotoserver._sshv1respondbytes(self._fout, rsp.data) |
|
54 | wireprotoserver._sshv1respondbytes(self._fout, rsp.data) | |
53 |
|
55 | |||
54 | super(prehelloserver, self).serve_forever() |
|
56 | super(prehelloserver, self).serve_forever() | |
@@ -72,8 +74,10 b' class upgradev2server(wireprotoserver.ss' | |||||
72 | self._fin.read(81) |
|
74 | self._fin.read(81) | |
73 |
|
75 | |||
74 | # Send the upgrade response. |
|
76 | # Send the upgrade response. | |
|
77 | proto = wireprotoserver.sshv1protocolhandler(self._ui, self._fin, | |||
|
78 | self._fout) | |||
75 | self._fout.write(b'upgraded %s %s\n' % (token, name)) |
|
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 | rsp = b'capabilities: %s' % servercaps.data |
|
81 | rsp = b'capabilities: %s' % servercaps.data | |
78 | self._fout.write(b'%d\n' % len(rsp)) |
|
82 | self._fout.write(b'%d\n' % len(rsp)) | |
79 | self._fout.write(rsp) |
|
83 | self._fout.write(rsp) |
@@ -23,8 +23,11 b' class SSHServerGetArgsTests(unittest.Tes' | |||||
23 |
|
23 | |||
24 | def assertparse(self, cmd, input, expected): |
|
24 | def assertparse(self, cmd, input, expected): | |
25 | server = mockserver(input) |
|
25 | server = mockserver(input) | |
|
26 | proto = wireprotoserver.sshv1protocolhandler(server._ui, | |||
|
27 | server._fin, | |||
|
28 | server._fout) | |||
26 | _func, spec = wireproto.commands[cmd] |
|
29 | _func, spec = wireproto.commands[cmd] | |
27 |
self.assertEqual( |
|
30 | self.assertEqual(proto.getargs(spec), expected) | |
28 |
|
31 | |||
29 | def mockserver(inbytes): |
|
32 | def mockserver(inbytes): | |
30 | ui = mockui(inbytes) |
|
33 | ui = mockui(inbytes) |
General Comments 0
You need to be logged in to leave comments.
Login now