Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 100d81e

Browse files
committed
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).
1 parent e0d9a83 commit 100d81e

1 file changed

Lines changed: 38 additions & 23 deletions

File tree

Lib/ftplib.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""An FTP client class and some helper functions.
22
3-
Based on RFC 959: File Transfer Protocol
4-
(FTP), by J. Postel and J. Reynolds
3+
Based on RFC 959: File Transfer Protocol (FTP), by J. Postel and J. Reynolds
54
65
Example:
76
@@ -235,7 +234,9 @@ def voidcmd(self, cmd):
235234
return self.voidresp()
236235

237236
def sendport(self, host, port):
238-
'''Send a PORT command with the current host and the given port number.'''
237+
'''Send a PORT command with the current host and the given
238+
port number.
239+
'''
239240
hbytes = string.splitfields(host, '.')
240241
pbytes = [`port/256`, `port%256`]
241242
bytes = hbytes + pbytes
@@ -253,25 +254,35 @@ def makeport(self):
253254
resp = self.sendport(host, port)
254255
return sock
255256

256-
def ntransfercmd(self, cmd):
257-
'''Initiate a transfer over the data connection.
258-
If the transfer is active, send a port command and
259-
the transfer command, and accept the connection.
260-
If the server is passive, send a pasv command, connect
261-
to it, and start the transfer command.
262-
Either way, return the socket for the connection and
263-
the expected size of the transfer. The expected size
264-
may be None if it could not be determined.'''
257+
def ntransfercmd(self, cmd, rest=None):
258+
"""Initiate a transfer over the data connection.
259+
260+
If the transfer is active, send a port command and the
261+
transfer command, and accept the connection. If the server is
262+
passive, send a pasv command, connect to it, and start the
263+
transfer command. Either way, return the socket for the
264+
connection and the expected size of the transfer. The
265+
expected size may be None if it could not be determined.
266+
267+
Optional `rest' argument can be a string that is sent as the
268+
argument to a RESTART command. This is essentially a server
269+
marker used to tell the server to skip over any data up to the
270+
given marker.
271+
"""
265272
size = None
266273
if self.passiveserver:
267274
host, port = parse227(self.sendcmd('PASV'))
268-
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
275+
conn=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
269276
conn.connect((host, port))
277+
if rest is not None:
278+
self.sendcmd("REST %s" % rest)
270279
resp = self.sendcmd(cmd)
271280
if resp[0] <> '1':
272281
raise error_reply, resp
273282
else:
274283
sock = self.makeport()
284+
if rest is not None:
285+
self.sendcmd("REST %s" % rest)
275286
resp = self.sendcmd(cmd)
276287
if resp[0] <> '1':
277288
raise error_reply, resp
@@ -281,10 +292,9 @@ def ntransfercmd(self, cmd):
281292
size = parse150(resp)
282293
return conn, size
283294

284-
def transfercmd(self, cmd):
285-
'''Initiate a transfer over the data connection. Returns
286-
the socket for the connection. See also ntransfercmd().'''
287-
return self.ntransfercmd(cmd)[0]
295+
def transfercmd(self, cmd, rest=None):
296+
"""Like nstransfercmd() but returns only the socket."""
297+
return self.ntransfercmd(cmd, rest)[0]
288298

289299
def login(self, user = '', passwd = '', acct = ''):
290300
'''Login, default anonymous.'''
@@ -312,13 +322,18 @@ def login(self, user = '', passwd = '', acct = ''):
312322
raise error_reply, resp
313323
return resp
314324

315-
def retrbinary(self, cmd, callback, blocksize=8192):
316-
'''Retrieve data in binary mode.
317-
The argument is a RETR command.
318-
The callback function is called for each block.
319-
This creates a new port for you'''
325+
def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
326+
"""Retrieve data in binary mode.
327+
328+
`cmd' is a RETR command. `callback' is a callback function is
329+
called for each block. No more than `blocksize' number of
330+
bytes will be read from the socket. Optional `rest' is passed
331+
to transfercmd().
332+
333+
A new port is created for you. Return the response code.
334+
"""
320335
self.voidcmd('TYPE I')
321-
conn = self.transfercmd(cmd)
336+
conn = self.transfercmd(cmd, rest)
322337
while 1:
323338
data = conn.recv(blocksize)
324339
if not data:

0 commit comments

Comments
 (0)