issue #275: ssh: state machine-ish filter_debug()
This commit is contained in:
parent
fbd5837cf2
commit
84fa3ff024
mitogen
|
@ -53,21 +53,6 @@ HOSTKEY_FAIL = 'host key verification failed.'
|
||||||
DEBUG_PREFIXES = ('debug1:', 'debug2:', 'debug3:')
|
DEBUG_PREFIXES = ('debug1:', 'debug2:', 'debug3:')
|
||||||
|
|
||||||
|
|
||||||
def _filter_debug(stream, it, buf):
|
|
||||||
while True:
|
|
||||||
if not buf.startswith(DEBUG_PREFIXES):
|
|
||||||
return buf
|
|
||||||
while '\n' in buf:
|
|
||||||
if not buf.startswith(DEBUG_PREFIXES):
|
|
||||||
return buf
|
|
||||||
line, _, buf = buf.partition('\n')
|
|
||||||
LOG.debug('%r: %s', stream, line.rstrip())
|
|
||||||
try:
|
|
||||||
buf += next(it)
|
|
||||||
except StopIteration:
|
|
||||||
return buf
|
|
||||||
|
|
||||||
|
|
||||||
def filter_debug(stream, it):
|
def filter_debug(stream, it):
|
||||||
"""
|
"""
|
||||||
Read line chunks from it, either yielding them directly, or building up and
|
Read line chunks from it, either yielding them directly, or building up and
|
||||||
|
@ -76,11 +61,33 @@ def filter_debug(stream, it):
|
||||||
This contains the mess of dealing with both line-oriented input, and partial
|
This contains the mess of dealing with both line-oriented input, and partial
|
||||||
lines such as the password prompt.
|
lines such as the password prompt.
|
||||||
"""
|
"""
|
||||||
|
state = 'start_of_line'
|
||||||
|
buf = ''
|
||||||
for chunk in it:
|
for chunk in it:
|
||||||
chunk = _filter_debug(stream, it, chunk)
|
buf += chunk
|
||||||
if chunk:
|
while buf:
|
||||||
for line in chunk.splitlines():
|
if state == 'start_of_line':
|
||||||
yield line
|
if len(buf) < 8:
|
||||||
|
# short read near the buffer limit, block waiting for at
|
||||||
|
# least 8 bytes so we can discern either a debug line, or
|
||||||
|
# the minimum desired interesting token from above
|
||||||
|
# ('password').
|
||||||
|
break
|
||||||
|
elif buf.startswith(DEBUG_PREFIXES):
|
||||||
|
state = 'in_debug'
|
||||||
|
else:
|
||||||
|
state = 'in_plain'
|
||||||
|
elif state == 'in_debug':
|
||||||
|
if '\n' not in buf:
|
||||||
|
break
|
||||||
|
line, _, buf = buf.partition('\n')
|
||||||
|
LOG.debug('%r: %s', stream, line.rstrip())
|
||||||
|
state = 'start_of_line'
|
||||||
|
elif state == 'in_plain':
|
||||||
|
line, nl, buf = buf.partition('\n')
|
||||||
|
yield line + nl
|
||||||
|
if nl:
|
||||||
|
state = 'start_of_line'
|
||||||
|
|
||||||
|
|
||||||
class PasswordError(mitogen.core.StreamError):
|
class PasswordError(mitogen.core.StreamError):
|
||||||
|
@ -222,7 +229,7 @@ class Stream(mitogen.parent.Stream):
|
||||||
|
|
||||||
for buf in filter_debug(self, it):
|
for buf in filter_debug(self, it):
|
||||||
LOG.debug('%r: received %r', self, buf)
|
LOG.debug('%r: received %r', self, buf)
|
||||||
if buf.endswith('EC0'):
|
if buf.endswith('EC0\n'):
|
||||||
self._router.broker.start_receive(self.tty_stream)
|
self._router.broker.start_receive(self.tty_stream)
|
||||||
self._ec0_received()
|
self._ec0_received()
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue