KrisCool Verbeux | Pour plus de flexibilité, j'ai implémenté une classe HTTPProgressConnection qui dérive de HTTPConnection en redéfinissant sa commande send()
Je fais l'envoi en passant par socket.send() au lieu de socket.sendall(), et j'ai ajouté la possibilité de mettre un callback à chaque appel de socket.send() pour renvoyer le nombre d'octets déjà envoyés et le nombre total d'octets.
Code :
- import httplib, urllib
- class HTTPProgressConnection(httplib.HTTPConnection):
- def __init__(self, host, port=None, strict=None):
- httplib.HTTPConnection.__init__(self, host, port, strict)
- self.progress_callback = None
- self.send_buffer_size = 1024
- def send(self, str):
- """Send `str' to the server and calls self.progress_callback() when data is actually sent"""
- if self.sock is None:
- if self.auto_open:
- self.connect()
- else:
- raise NotConnected()
- if self.debuglevel > 0:
- print "send:", repr(str)
- try:
- # Start of modification to the original HTTPConnection.send()
- # Set the callback
- if callable(self.progress_callback):
- callback = self.progress_callback
- else:
- callback = lambda c,t: 0
- total_bytecount = 0
- total_size = len(str)
- while total_bytecount < total_size:
- total_bytecount += self.sock.send(str[total_bytecount:self.send_buffer_size])
- callback(total_bitecount, total_size)
- # End of the modification or the original HTTPConnection.send()
- except socket.error, v:
- if v[0] == 32: # Broken pipe
- self.close()
- raise
- if __name__ == "__main__":
- def simple_callback(current, total):
- print "%(current)d / %(total)" % (current, total)
- params = urllib.urlencode({'q': 'python c\'est bon !'})
- hpc = HTTPProgressConnection('www.google.fr', 80)
- hpc.progress_callback = simple_callback
- print 'hpc.request():'
- hpc.request('GET', '/search', params)
|
Le constructeur de HTTPProgressConnection est le même que celui de HTTPConnection, et définit deux attributs supplémentaires:
- progress_callback, qui est la fonction de callback à appeler lors de chaque envoi de données, et qui doit recevoir deux arguments
- send_buffer_size, qui est un nom trompeur (à changer) qui définit la taille des données envoyées par appel à socket.send()
J'ai pas pu tester en l'état parce que cette classe ne supporte pas les proxies, et que j'en ai un à ma boîte. ---------------
Loose Change Lies | Bars | Last.fm
|