2010-07-12 13 views
29

Estoy escribiendo un cliente REST para Elgg usando Python, e incluso cuando la solicitud se realiza correctamente, me sale esto en respuesta:Python httplib ResponseNotReady

Traceback (most recent call last): 
    File "testclient.py", line 94, in <module> 
    result = sendMessage(token, h1) 
    File "testclient.py", line 46, in sendMessage 
    res = h1.getresponse().read() 
    File "C:\Python25\lib\httplib.py", line 918, in getresponse 
    raise ResponseNotReady() 
httplib.ResponseNotReady 

En cuanto a la cabecera, veo ('Content-Length ',' 5749 '), entonces sé que hay una página allí, pero no puedo usar .read() para verla porque aparece la excepción. ¿Qué significa ResponseNotReady y por qué no puedo ver el contenido que se devolvió?

+0

¿Estás reutilizando la conexión? – ChristopheD

+0

De hecho. Curiosamente, algunas veces funciona y otras no. Sin embargo, no puedo determinar qué comportamiento determina eso. – directedition

Respuesta

35

Asegúrese de no reutilizar el mismo objeto de una conexión anterior. Tocará esto una vez que el servidor keep-alive finalice y el socket se cierre.

+1

Generalmente, como regla, no me molesto en intentar reutilizar los objetos HttpRequest a menos que tenga una necesidad específica y orientada al rendimiento para hacerlo. Sólo 'em single-shot' – rossipedia

+0

En mi caso, agregar 'preload_content = False' resolvió el problema. Aquí está el fragmento: 'http = urllib3.PoolManager (threadsNo, maxsize = threadsNo, block = True); request = http.request ('GET', queryUrl, preload_content = False) 'Parece que' request.release_conn() 'no libera realmente el objeto de conexión anterior a menos que el parámetro anterior se pase a http.request. Más detalles aquí: https://urllib3.readthedocs.org/en/latest/pools.html – dex

2

yo estaba corriendo en esta misma excepción hoy en día, el uso de este código:

conn = httplib.HTTPConnection(self._host, self._port) 
    conn.putrequest('GET', 
     '/retrieve?id={0}'.format(parsed_store_response['id'])) 
    retr_response = conn.getresponse() 

no me di cuenta de que yo estaba usando en lugar de putrequestrequest; Estaba mezclando mis interfaces. ResponseNotReady se ha generado porque todavía no he enviado la solicitud.

49

Las respuestas anteriores son correctas, pero hay otro caso en el que podría obtener esa excepción: si realiza múltiples solicitudes sin leer completamente la respuesta intermedia.

Por ejemplo:

conn.request('PUT',...) 
conn.request('GET',...) 
# will not work: raises ResponseNotReady 

conn.request('PUT,...) 
r = conn.getresponse() 
r.read() # <-- that's the important call! 
conn.request('GET',...) 
r = conn.getresponse() 
r.read() # <-- same thing 

y así sucesivamente.

+0

Eso es lo que necesitaba .read() para poder reutilizar mi conexión. – schwiz

+0

es .read() caro. ¿Qué pasa si no me importa la respuesta? ¿Puedo hacer que funcione más rápido?> – SoulMan

+2

@ronnefeldt, Python docs en https://docs.python.org/3/library/http.client.html tiene la siguiente nota: "Tenga en cuenta que debe haber leído toda la respuesta antes puede enviar una nueva solicitud al servidor ". – mvsagar

0

Además, errores como este pueden ocurrir cuando el servidor envía una respuesta sin un encabezado Content-Length, lo que paralizará el estado del cliente HTTP si se usa Keep-Alive y se envía otra solicitud sobre el mismo socket.

0

Esto también puede ocurrir si un servidor de seguridad bloquea la conexión.