【问题标题】:Python httplib ResponseNotReadyPython httplib ResponseNotReady
【发布时间】:2010-07-12 19:24:53
【问题描述】:

我正在使用 python 为 elgg 编写一个 REST 客户端,即使请求成功,我也会得到以下响应:

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

查看标题,我看到 ('content-length', '5749'),所以我知道那里有一个页面,但我无法使用 .read() 来查看它,因为出现了异常。 ResponseNotReady 是什么意思,为什么我看不到返回的内容?

【问题讨论】:

  • 你在重用连接吗?
  • 确实如此。奇怪的是,有时它有效,有时则无效。不过,我无法确定是什么行为决定了这一点。

标签: python http rest httplib


【解决方案1】:

以前的答案是正确的,但还有另一种情况可能会出现该异常:

在不完全读取任何中间响应的情况下发出多个请求。

例如:

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

等等。

【讨论】:

  • 这就是我需要的 .read() 以便我可以重用我的连接。
  • .read() 很昂贵。如果我不关心响应怎么办?我可以让它跑得更快吗?>
  • @ronnefeldt,docs.python.org/3/library/http.client.html 的 Python 文档有以下注释:“请注意,您必须先阅读整个响应,然后才能向服务器发送新请求。”。
  • 如果你没有这么说,我会在接下来的几个小时甚至几天里感到非常沮丧。谢谢你
【解决方案2】:

确保您没有重复使用之前连接中的相同对象。一旦服务器 keep-alive 结束并且套接字关闭,您将点击它。

【讨论】:

  • 一般来说,我不会费心尝试重用 HttpRequest 对象,除非我有特定的、性能驱动的需要这样做。只是单发
  • 就我而言,添加preload_content=False 解决了这个问题。这是sn-p:http = urllib3.PoolManager(threadsNo, maxsize=threadsNo, block=True); request = http.request('GET', queryUrl, preload_content=False) 看起来request.release_conn() 并没有真正释放之前的连接对象,除非将上述参数传递给http.request。更多细节在这里:urllib3.readthedocs.org/en/latest/pools.html
【解决方案3】:

此外,当服务器发送没有 Content-Length 标头的响应时,可能会发生此类错误,如果使用 Keep-Alive 并且通过同一套接字发送另一个请求,这将削弱 HTTP 客户端的状态。

【讨论】:

    【解决方案4】:

    我今天也遇到了同样的异常,使用以下代码:

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

    我没有注意到我使用的是putrequest 而不是request;我正在混合我的界面。 ResponseNotReady 被提出是因为我还没有真正发送请求。

    【讨论】:

      【解决方案5】:

      如果防火墙阻止了连接,也会发生这种情况。

      【讨论】:

        【解决方案6】:

        无法为@Bokeh 的答案添加评论;因为我在这个平台上还没有必要的声誉。

        所以,添加为答案:Bokeh 的答案对我有用。

        我试图在同一个连接对象上按顺序传输多个请求。对于少数回复,我想稍后处理回复,因此错过了阅读回复。

        根据我的经验,我支持 Bokeh 的回答:

        response.read() 在每个请求之后都是必须的。即使您希望或不希望处理响应。

        在我看来,如果没有 Bokeh 的回答,这个问题将是不完整的。 谢谢@Bokeh

        【讨论】:

          猜你喜欢
          • 2011-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-31
          相关资源
          最近更新 更多