5 ans plus tard, mais nous espérons que cela aidera quelqu'un d'autre ...
Je détruisait mon cerveau en essayant de comprendre. Mon problème était un serveur qui retournait du contenu corrompu et qui restituait donc moins de données qu'il ne le pensait. Je suis venu avec une solution désagréable qui semble fonctionner correctement. Ici, il va:
# NOTE I directly disabling blocking is not necessary but it represents
# an important piece to the problem so I am leaving it here.
# http_response.fp._sock.socket.setblocking(0)
http_response.fp._sock.settimeout(read_timeout)
http_response.read(chunk_size)
NOTE Cette solution fonctionne également pour les demandes pythonQUELQUE bibliothèque qui implémente les prises de python normales (qui devraient être tous?).Il vous suffit d'aller quelques niveaux plus profonds:
resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
resp.raw.read(chunk_size)
A ce jour, je ne l'ai pas essayé ce qui suit, mais en théorie il devrait fonctionner:
resp = requests.get(some_url, stream=True)
resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
for chunk in resp.iter_content(chunk_size):
# do stuff
Explication
I tombé sur cette approche lors de la lecture de cette question SO pour setting a timeout on socket.recv
À la fin de la journée, toute demande http a une prise. Pour le httplib, cette socket est située à resp.raw._fp.fp._sock.socket
. Le resp.raw._fp.fp._sock
est un socket._fileobj
(que honnêtement je n'ai pas regardé loin dans) et j'imagine que c'est la méthode settimeout
le place en interne sur l'attribut socket
.
liée: [Lire le délai d'expiration en utilisant urllib2 ou toute autre bibliothèque http] (http://stackoverflow.com/q/9548869/4279) – jfs