import httplib, socket class ProgressReportingHTTPConnection(httplib.HTTPConnection): """An HTTPConnection which sends data in small blocks and calls an optional callback so you can see that it's making progress. Pass the callback function as progress_callback to constructor. The callback function takes two parameters, i and l; i is the amount of data transferred, l is the total amount of data being sent. Also allows you to abort connections. """ def __init__(self, host, port=None, strict=None, progress_callback=None): httplib.HTTPConnection.__init__(self, host, port, strict) self.progress_callback = progress_callback self.ABORT_CONNECTION = False def abort_connection(self): self.ABORT_CONNECTION = True def send(self, str): """Send `str' to the server.""" if self.sock is None: if self.auto_open: try: self.connect() except: self.connect() # try one more time! else: raise NotConnected() # send the data to the server. if we get a broken pipe, then close # the socket. we want to reconnect when somebody tries to send again. # # NOTE: we DO propagate the error, though, because we cannot simply # ignore the error... the caller will know if they can retry. if self.debuglevel > 0: print "send:", repr(str) try: if self.progress_callback: BLOCK_SIZE = 2048 # 2K blocks l = len(str) for i in range(0,l,BLOCK_SIZE): self.sock.sendall(str[i:i+BLOCK_SIZE]) self.progress_callback(i,l) if self.ABORT_CONNECTION: self.close() return # report completion self.progress_callback(l,l) else: self.sock.sendall(str) except socket.error, v: if v[0] == 32: # Broken pipe self.close() raise