这是httplib2的一个bug吗?

7
我的Python程序使用httplib2.Http来进行HTTP请求。一旦我需要生成一个请求,我就会创建一个httplib2.Http对象,因此我的程序会频繁地创建/销毁httplib2.Http对象。
我发现,由于打开的文件数达到了最大值,我的程序很容易崩溃。在检查/proc//fd时,发现有太多的打开套接字fd。这个问题让我不得不深入研究httplib2源代码。
然后我发现,在httplib2.Http._conn_request方法中,有如下代码:
        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
        break

这表明当HTTP方法为HEAD时,套接字才会关闭。也许httplib2想要重用该套接字。但是Http类没有close()方法。这意味着当我发出Http请求时,套接字将不会关闭,直到我的进程终止。
然后我修改了代码:
        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
                conn.close() # I ADD THIS CLOSE
        break

之后,我的程序运行良好。

但我仍然很好奇这是否真的是httplib2的错误,因为httplib2是一个非常古老和常见的库。

1个回答

7
不,连接不关闭的事实并非错误,它是为了重用连接以供下一个请求而必要的。 httplib2 的编写方式是等待服务器关闭连接或超时,它不会主动关闭连接(除非发生错误)。如果连接已经关闭,httplib2 将在下次使用它时尝试重新建立连接。关闭连接(如您对源代码的补丁所做的)将使这种重用变得不可能,每个请求都必须使用自己的连接。销毁 httplib2.Http 对象应该会自动关闭打开的连接,因为它们只被引用在其 connections 字典中,所以如果您没有保留对创建的 Http 对象的任何引用,它应该可以正常工作。您确定没有任何悬挂的引用吗?或者您可以在您的请求中传递一个 Connnection: close 头。
http.request("http://example.org", headers={'Connection': 'close'})

这会导致服务器在每个请求后关闭连接。或者,您可以尝试手动关闭对象的connections字典中的所有连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接