Resuming with (ftplib/httplib)?
Henning Schroeder
hschroeder at gmx.net
Wed Aug 11 07:09:14 EDT 1999
Orlando Vazquez <ovazquez at sprint.ca> wrote:
> So my question is, how can I, using ftplib and httplib, resume a
> download? Is it possible? Has this been done before? Any code someone
> would be willing to share? I would appreciate it soo much. :-)
HTTP version 1.1 supports byte ranges. There is an interesting article in
ApacheWeek (http://www.apacheweek.org) about HTTP 1.1.
The ftp-protocoll has a REST command to resume transfers. See the hack
below which works for me.
Henning
------------------------------------------------------------
# Module xftplib.py
from ftplib import *
class XFTP(FTP):
def size(self, filename):
self.voidcmd("TYPE I") #seems necessary to get the *right* size
return FTP.size(self, filename)
def rest(self, start):
resp = self.sendcmd("REST %s" % start)
if resp[:3] <> "350": raise error_reply, resp
def ntransfercmd(self, cmd, resume):
'''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.'''
size = None
if self.passiveserver:
host, port = parse227(self.sendcmd('PASV'))
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.connect(host, port)
if resume: self.rest(resume)
resp = self.sendcmd(cmd)
if resp[0] <> '1':raise error_reply, resp
else:
sock = self.makeport()
if resume: self.rest(resume)
resp = self.sendcmd(cmd)
if resp[0] <> '1':
raise error_reply, resp
conn, sockaddr = sock.accept()
if resp[:3] == '150':
# this is conditional in case we received a 125
size = parse150(resp)
return conn, size
def transfercmd(self, cmd, resume=0):
'''Initiate a transfer over the data connection. Returns
the socket for the connection. See also ntransfercmd().'''
return self.ntransfercmd(cmd, resume)[0]
def retrbinary(self, cmd, callback, resume=0, 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'''
self.voidcmd('TYPE I')
conn = self.transfercmd(cmd, resume)
while 1:
data = conn.recv(blocksize)
if not data:
break
callback(data)
conn.close()
return self.voidresp()
More information about the Python-list
mailing list