summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--paramiko/sftp.py18
-rw-r--r--paramiko/transport.py16
2 files changed, 25 insertions, 9 deletions
diff --git a/paramiko/sftp.py b/paramiko/sftp.py
index 0e7f48f7..d5948ed9 100644
--- a/paramiko/sftp.py
+++ b/paramiko/sftp.py
@@ -15,7 +15,7 @@
# details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with Foobar; if not, write to the Free Software Foundation, Inc.,
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
import struct, socket
@@ -121,6 +121,11 @@ class SFTPError (Exception):
class SFTPFile (BufferedFile):
+
+ # some sftp servers will choke if you send read/write requests larger than
+ # this size.
+ MAX_REQUEST_SIZE = 32768
+
def __init__(self, sftp, handle, mode='r', bufsize=-1):
BufferedFile.__init__(self)
self.sftp = sftp
@@ -143,16 +148,23 @@ class SFTPFile (BufferedFile):
self.sftp._request(CMD_CLOSE, self.handle)
def _read(self, size):
+ size = min(size, self.MAX_REQUEST_SIZE)
t, msg = self.sftp._request(CMD_READ, self.handle, long(self._realpos), int(size))
if t != CMD_DATA:
raise SFTPError('Expected data')
return msg.get_string()
def _write(self, data):
- t, msg = self.sftp._request(CMD_WRITE, self.handle, long(self._realpos), str(data))
+ offset = 0
+ while offset < len(data):
+ chunk = min(len(data) - offset, self.MAX_REQUEST_SIZE)
+ t, msg = self.sftp._request(CMD_WRITE, self.handle, long(self._realpos + offset),
+ str(data[offset : offset + chunk]))
+ offset += chunk
return len(data)
def seek(self, offset, whence=0):
+ self.flush()
if whence == self.SEEK_SET:
self._realpos = self._pos = offset
elif whence == self.SEEK_CUR:
@@ -160,7 +172,7 @@ class SFTPFile (BufferedFile):
self._pos += offset
else:
self._realpos = self._pos = self._get_size() + offset
- self._rbuffer = self._wbuffer = ''
+ self._rbuffer = ''
def stat(self):
"""
diff --git a/paramiko/transport.py b/paramiko/transport.py
index ac3560cd..06f75801 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -15,7 +15,7 @@
# details.
#
# You should have received a copy of the GNU Lesser General Public License
-# along with Foobar; if not, write to the Free Software Foundation, Inc.,
+# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
"""
@@ -162,8 +162,8 @@ class BaseTransport (threading.Thread):
self.channel_counter = 1
self.logger = logging.getLogger('paramiko.transport')
self.window_size = 65536
- self.max_packet_size = 8192
- self.ultra_debug = 0
+ self.max_packet_size = 32768
+ self.ultra_debug = False
self.saved_exception = None
# used for noticing when to re-key:
self.received_bytes = 0
@@ -792,7 +792,9 @@ class BaseTransport (threading.Thread):
def _send_message(self, data):
# FIXME: should we check for rekeying here too?
# encrypt this sucka
- packet = self._build_packet(str(data))
+ data = str(data)
+ self._log(DEBUG, 'Write packet $%x, length %d' % (ord(data[0]), len(data)))
+ packet = self._build_packet(data)
if self.ultra_debug:
self._log(DEBUG, util.format_binary(packet, 'OUT: '))
if self.engine_out != None:
@@ -861,8 +863,10 @@ class BaseTransport (threading.Thread):
self.received_packets_overflow += 1
if self.received_packets_overflow >= 20:
raise SSHException('Remote transport is ignoring rekey requests')
-
- return ord(payload[0]), msg
+
+ cmd = ord(payload[0])
+ self._log(DEBUG, 'Read packet $%x, length %d' % (cmd, len(payload)))
+ return cmd, msg
def _set_K_H(self, k, h):
"used by a kex object to set the K (root key) and H (exchange hash)"