简体   繁体   English

这是httplib2的错误吗?

[英]Is this a bug of httplib2

My python program use httplib2.Http to make http request. 我的python程序使用httplib2.Http来发出http请求。 Once I need to generate a request, I create a httplib2.Http object, so that my program will frequently create/destroy httplib2.Http objects. 一旦我需要生成一个请求,我创建一个httplib2.Http对象,以便我的程序经常创建/销毁httplib2.Http对象。

I found my program was easy to crash due to reach max number of open files. 我发现由于达到最大打开文件数,我的程序很容易崩溃。 Checking /proc//fd, there were too many open socket fds. 检查/ proc // fd,打开套接字fds太多了。 The problem made me to have to dig into httplib2 source code. 这个问题使我不得不深入研究httplib2源代码。

Then I found that, in httplib2.Http._conn_request method, there was code like this: 然后我发现,在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

This shows that socket is only closed when http method is HEAD. 这表明套接字仅在http方法为HEAD时关闭。 Maybe httplib2 wanted somehow to reuse the socket. 也许httplib2想要以某种方式重用套接字。 But Http class doesn't have a close() method. 但是Http类没有close()方法。 That mean when I makes a Http request, the socket will not close until my process terminates. 这意味着当我发出Http请求时,套接字将不会关闭,直到我的进程终止。

Then I modified the code: 然后我修改了代码:

        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

After that, my program worked well. 在那之后,我的计划运作良好。

But I'm still curious if that's really httplib2's bug given that httplib2 is a very old and common lib. 但我仍然很好奇,如果这是httplib2的错误,因为httplib2是一个非常古老而常见的lib。

No, the fact that the connections are not closed is not a bug, it is necessary to reuse a connection for the next request. 不,连接未关闭的事实不是错误,必须为下一个请求重用连接。

The way httplib2 is written, it waits for the server to close the connection or for it to time out, it doesn't actively close them (execept on errors). 编写httplib2的方式,它等待服务器关闭连接或等待超时,它不会主动关闭它们(除了错误)。 If a connection has been closed, httplib2 will just try to reestablish it the next time it's used. 如果连接已关闭, httplib2将在下次使用时尝试重新建立连接。

Closing the connection (as your patch to the source does) would make this impossible, every request would have to use it's own connection. 关闭连接(作为源的补丁)会使这变得不可能,每个请求都必须使用它自己的连接。

Destroying the httplib2.Http object should automatically close the open connections as they are only referenced in it's connections dictionary, so if you don't keep any references to the Http objects you created it should work. 销毁httplib2.Http对象应该会自动关闭打开的连接,因为它们只在它的connections字典中引用,所以如果你不保留对你创建的Http对象的任何引用,它应该可以工作。 Are you sure you don't have any references hanging around? 你确定你没有任何引用吗?

Alternatively you could pass a Connnection: close header to your request: 或者,您可以将Connnection: close标头传递给您的请求:

http.request("http://example.org", headers={'Connection': 'close'})

That should cause the server to close the connection after each request. 这应该导致服务器在每次请求后关闭连接。 Or, you could try to manually close all connections in the object's connections dict. 或者,您可以尝试手动关闭对象connections dict中的所有连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM