##// END OF EJS Templates
wireprotoserver: move SSH server operation to a standalone function...
Gregory Szorc -
r36232:3b3a987b default
parent child Browse files
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, self._proto)
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(server._proto.getargs(spec), expected)
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