summaryrefslogtreecommitdiff
path: root/paramiko/proxy.py
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2014-02-13 13:44:27 -0800
committerJeff Forcier <jeff@bitprophet.org>2014-02-13 13:44:27 -0800
commit4402f67fa61c1c43a838d4414e42ad8047876ebf (patch)
treee45092d02a4034248dd6872a9e88af19dcc9fd0b /paramiko/proxy.py
parent244e09f57a6670fbdda9979882d81b1d7e40b75c (diff)
downloadparamiko-4402f67fa61c1c43a838d4414e42ad8047876ebf.tar.gz
Don't drop/lose data when our inner timeout goges off.
Diffstat (limited to 'paramiko/proxy.py')
-rw-r--r--paramiko/proxy.py17
1 files changed, 8 insertions, 9 deletions
diff --git a/paramiko/proxy.py b/paramiko/proxy.py
index a24fbb2d..722590ce 100644
--- a/paramiko/proxy.py
+++ b/paramiko/proxy.py
@@ -52,6 +52,7 @@ class ProxyCommand(object):
self.cmd = shlsplit(command_line)
self.process = Popen(self.cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
self.timeout = None
+ self.buffer = []
def send(self, content):
"""
@@ -83,23 +84,21 @@ class ProxyCommand(object):
"""
try:
start = datetime.now()
- read = []
- while len(read) < size:
+ while len(self.buffer) < size:
if self.timeout is not None:
elapsed = (datetime.now() - start).microseconds
timeout = self.timeout * 1000 * 1000 # to microseconds
- # Unsure why the 'default' timeout is too short here -
- # causes us to raise before e.g. the SSH banner is read,
- # probably generally awful for slow connections.
- # Try inflating it some.
- timeout = timeout * 2
if elapsed >= timeout:
raise socket.timeout()
r, w, x = select([self.process.stdout], [], [], 0.0)
if r and r[0] == self.process.stdout:
b = os.read(self.process.stdout.fileno(), 1)
- read.append(b)
- result = ''.join(read)
+ # Store in class-level buffer for persistence across
+ # timeouts; this makes us act more like a real socket
+ # (where timeouts don't actually drop data.)
+ self.buffer.append(b)
+ result = ''.join(self.buffer)
+ self.buffer = []
return result
except IOError, e:
raise ProxyCommandFailure(' '.join(self.cmd), e.strerror)