summaryrefslogtreecommitdiffstats
path: root/Lib/ftplib.py
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2000-09-01 06:09:23 (GMT)
committerBarry Warsaw <barry@python.org>2000-09-01 06:09:23 (GMT)
commit100d81e8e3d06a82a6d9cefee209ac7862951720 (patch)
tree904ce1f132a2927fe801fb15415e3144b84b0012 /Lib/ftplib.py
parente0d9a83bea5f78964217fd1f2dd82027841c9444 (diff)
downloadcpython-100d81e8e3d06a82a6d9cefee209ac7862951720.zip
cpython-100d81e8e3d06a82a6d9cefee209ac7862951720.tar.gz
cpython-100d81e8e3d06a82a6d9cefee209ac7862951720.tar.bz2
Added support for RFC 959's REST command (restart), closing SF patch
#101187, which some modifications. Specifically, ntransfercmd(), transfercmd(), and retrbinary() all grow an optional `rest' argument, which if not None, is used as the argument to an FTP REST comman dbefore the socket is returned. Differences from the SF patch: - always compare against None with `is' or `is not' instead of == or != - no parens around conditional - RFC 959 defines the argument to REST is a string containing any ASCII characters in the range [33..126]. Therefore, we use the %s format character instead of %f or %d as suggested in the patch's comments. Note that we do /not/ sanity checkthe contents of the rest argument (but we'll document this in the library reference manual).
Diffstat (limited to 'Lib/ftplib.py')
-rw-r--r--Lib/ftplib.py61
1 files changed, 38 insertions, 23 deletions
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index a15c412..429e834 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -1,7 +1,6 @@
"""An FTP client class and some helper functions.
-Based on RFC 959: File Transfer Protocol
-(FTP), by J. Postel and J. Reynolds
+Based on RFC 959: File Transfer Protocol (FTP), by J. Postel and J. Reynolds
Example:
@@ -235,7 +234,9 @@ class FTP:
return self.voidresp()
def sendport(self, host, port):
- '''Send a PORT command with the current host and the given port number.'''
+ '''Send a PORT command with the current host and the given
+ port number.
+ '''
hbytes = string.splitfields(host, '.')
pbytes = [`port/256`, `port%256`]
bytes = hbytes + pbytes
@@ -253,25 +254,35 @@ class FTP:
resp = self.sendport(host, port)
return sock
- def ntransfercmd(self, cmd):
- '''Initiate a transfer over the data connection.
- If the transfer is active, send a port command and
- the transfer command, and accept the connection.
- If the server is passive, send a pasv command, connect
- to it, and start the transfer command.
- Either way, return the socket for the connection and
- the expected size of the transfer. The expected size
- may be None if it could not be determined.'''
+ def ntransfercmd(self, cmd, rest=None):
+ """Initiate a transfer over the data connection.
+
+ If the transfer is active, send a port command and the
+ transfer command, and accept the connection. If the server is
+ passive, send a pasv command, connect to it, and start the
+ transfer command. Either way, return the socket for the
+ connection and the expected size of the transfer. The
+ expected size may be None if it could not be determined.
+
+ Optional `rest' argument can be a string that is sent as the
+ argument to a RESTART command. This is essentially a server
+ marker used to tell the server to skip over any data up to the
+ given marker.
+ """
size = None
if self.passiveserver:
host, port = parse227(self.sendcmd('PASV'))
- conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ conn=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.connect((host, port))
+ if rest is not None:
+ self.sendcmd("REST %s" % rest)
resp = self.sendcmd(cmd)
if resp[0] <> '1':
raise error_reply, resp
else:
sock = self.makeport()
+ if rest is not None:
+ self.sendcmd("REST %s" % rest)
resp = self.sendcmd(cmd)
if resp[0] <> '1':
raise error_reply, resp
@@ -281,10 +292,9 @@ class FTP:
size = parse150(resp)
return conn, size
- def transfercmd(self, cmd):
- '''Initiate a transfer over the data connection. Returns
- the socket for the connection. See also ntransfercmd().'''
- return self.ntransfercmd(cmd)[0]
+ def transfercmd(self, cmd, rest=None):
+ """Like nstransfercmd() but returns only the socket."""
+ return self.ntransfercmd(cmd, rest)[0]
def login(self, user = '', passwd = '', acct = ''):
'''Login, default anonymous.'''
@@ -312,13 +322,18 @@ class FTP:
raise error_reply, resp
return resp
- def retrbinary(self, cmd, callback, blocksize=8192):
- '''Retrieve data in binary mode.
- The argument is a RETR command.
- The callback function is called for each block.
- This creates a new port for you'''
+ def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
+ """Retrieve data in binary mode.
+
+ `cmd' is a RETR command. `callback' is a callback function is
+ called for each block. No more than `blocksize' number of
+ bytes will be read from the socket. Optional `rest' is passed
+ to transfercmd().
+
+ A new port is created for you. Return the response code.
+ """
self.voidcmd('TYPE I')
- conn = self.transfercmd(cmd)
+ conn = self.transfercmd(cmd, rest)
while 1:
data = conn.recv(blocksize)
if not data: