2010-07-12 4 views
29

Ich bin ein REST-Client für elgg mit Python zu schreiben, und selbst dann, wenn die Anforderung erfolgreich ist, erhalte ich diese als Antwort: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 

im Header der Suche, ich sehe ("Content-Length ',' 5749 '), also weiß ich, dass dort eine Seite ist, aber ich kann .read() nicht verwenden, um sie zu sehen, weil die Ausnahme auftaucht. Was bedeutet ResponseNotReady und warum kann ich den zurückgegebenen Inhalt nicht sehen?

+0

Verwenden Sie die Verbindung erneut? – ChristopheD

+0

In der Tat. Seltsamerweise funktioniert es manchmal und manchmal nicht. Ich kann jedoch nicht bestimmen, welches Verhalten das bestimmt. – directedition

Antwort

35

Stellen Sie sicher, dass Sie das gleiche Objekt nicht von einer vorherigen Verbindung wiederverwenden. Sie werden dies einmal der Server Keep-Alive endet und der Sockel schließt.

+1

Im Allgemeinen versuche ich nicht, HttpRequest-Objekte wiederzuverwenden, es sei denn, ich habe eine spezielle, leistungsgesteuerte Notwendigkeit, dies zu tun. Just single-shot 'em – rossipedia

+0

In meinem Fall löste das Hinzufügen von 'preload_content = False' das Problem. Hier ist das Snippet: 'http = urllib3.PoolManager (threadsNo, maxsize = threadsNo, block = True); request = http.request ('GET', queryUrl, preload_content = False) 'Es sieht so aus als ob 'request.release_conn()' das vorherige Verbindungsobjekt nicht wirklich freigibt, es sei denn, der obige Parameter wird an http.request übergeben. Mehr Details hier: https://urllib3.readthedocs.org/en/latest/pools.html – dex

2

Ich war heute in dieselbe Ausnahme ausgeführt wird, mit diesem Code:

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

Ich habe nicht bemerkt, dass ich putrequest wurde mit eher als request; Ich habe meine Schnittstellen gemischt. ResponseNotReady wird ausgelöst, weil ich die Anfrage noch nicht gesendet habe.

49

Vorherige Antworten sind korrekt, aber es gibt einen anderen Fall, in dem Sie diese Ausnahme erhalten könnten: es ist, wenn Sie mehrere Anfragen ohne die Zwischenantwort vollständig lesen.

Zum Beispiel:

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 

und so weiter.

+0

Das war, was ich .read() brauchte, damit ich meine Verbindung wiederverwenden kann. – schwiz

+0

ist .read() teuer. Was passiert, wenn mir die Antwort egal ist? Kann ich es schneller laufen lassen?> – SoulMan

+2

@ronnefeldt, Python docs unter https://docs.python.org/3/library/http.client.html hat den folgenden Hinweis: "Beachten Sie, dass Sie zuvor die gesamte Antwort gelesen haben müssen Sie können eine neue Anfrage an den Server senden. ". – mvsagar

0

Darüber hinaus können Fehler wie dieser auftreten, wenn der Server eine Antwort ohne Content-Length-Header sendet, die den Status des HTTP-Clients verkrüppeln wird, wenn Keep-Alive verwendet wird und eine andere Anforderung über denselben Socket gesendet wird.

0

Dies kann auch auftreten, wenn eine Firewall die Verbindung blockiert.

Verwandte Themen