基本的HTTPServer挂在“ socket.readinto:返回self._sock.recv_into(b)”处

时间:2018-08-27 22:00:03

标签: python python-3.x httpserver

我有一个非常基本的http.server.HTTPServer实现,我正在Python 3.6中自转。我正在使用它来针对Google Analytics(分析)API验证OAuth2。按照标准,我已经创建了一个简单的句柄来接收OAuth2授予​​密钥,并且正在使用serve_forever()方法。但是,用于永久创建服务的线程正在挂起,并且似乎深陷在Python 3.6实现中。

有趣的是,在这种情况下,我认为我的代码根本不重要。查看我设置用于调试的监听器报告的调用堆栈:

service_action started
service_action complete
service_action started
service_action complete
service_action started
service_action complete
service_action started
service_action complete
"socketserver.BaseServer.serve_forever : self._handle_request_noblock()"
"socketserver.BaseServer._handle_request_noblock : self.get_request()"
"socketserver.BaseServer._handle_noblock_request : self.process_request()"
"socketserver.BaseServer.process_request : self.finish_request()"
"socketserver.BaseServer.finish_request : self.RequestHandlerClass(request, client_address, self) #  request == <socket.socket fd=1828, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 57504)>,  client_address == ('127.0.0.1', 57504),  self == <MDGCoreLib.Utilities.HttpServer.Server.Server object at 0x0000026304E3FC88>"
"socketserver.BaseRequestHandler.__init__ : set self.client_address"
"socketserver.BaseRequestHandler.__init__ : set self.server"
"socketserver.BaseRequestHandler.__init__ : setup()"
"socketserver.StreamRequestHandler.setup : self.connection = self.request"
"socketserver.BaseRequestHandler.__init__ : self.handle()"
"server.BaseHttpRequestHandler.handle  : self.close_connection = True"
"server.BaseHTTPServer.handle_one_request : self.raw_requestline = self.rfile.readline(65537)"
"socket.readinto : self._checkClosed()"
"socket.readinto : return self._sock.recv_into(b)  #b == <memory at 0x0000026304E38C48>"
"server.BaseHTTPHandler.handle_one_request : if len(self.raw_requestline) > 65536"
"server.BaseHTTPHandler.handle_one_request : if not self.raw_requestline"
"server.BaseHTTPHandler.handle_one_request : if not self.parse_request()"
"server.BaseHTTPHandler.handle_one_request : if not hassattr(self, mname)"
#My handler runs
*"OAuthGrantRequestHandler : self.send_response"
127.0.0.1 - - [27/Aug/2018 14:35:16] "GET /?(REDACTED) HTTP/1.1" 200 -
Request handler completed*
#My handler finishes

Parent thread : joining Thread 2
"server.BaseHTTPHandler.handle_one_request : flushing wfile to socket finishing request"
"socketserver.BaseRequestHandler.__init__ : self.finish()"
"socketserver.StreamRequestHandler.finish : "
"socketserver.BaseServer.process_request : self.shutdown_request"
service_action started
service_action complete
"socketserver.BaseServer.serve_forever : self._handle_request_noblock()"
"socketserver.BaseServer._handle_request_noblock : self.get_request()"
"socketserver.BaseServer._handle_noblock_request : self.process_request()"
"socketserver.BaseServer.process_request : self.finish_request()"
"socketserver.BaseServer.finish_request : self.RequestHandlerClass(request, client_address, self) #  request == <socket.socket fd=1840, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 57505)>,  client_address == ('127.0.0.1', 57505),  self == <MDGCoreLib.Utilities.HttpServer.Server.Server object at 0x0000026304E3FC88>"
"socketserver.BaseRequestHandler.__init__ : set self.client_address"
"socketserver.BaseRequestHandler.__init__ : set self.server"
"socketserver.BaseRequestHandler.__init__ : setup()"
"socketserver.StreamRequestHandler.setup : self.connection = self.request"
"socketserver.BaseRequestHandler.__init__ : self.handle()"
"server.BaseHttpRequestHandler.handle  : self.close_connection = True"
"server.BaseHTTPServer.handle_one_request : self.raw_requestline = self.rfile.readline(65537)"
"socket.readinto : self._checkClosed()"
"socket.readinto : return self._sock.recv_into(b)  #b == <memory at 0x0000026304E38C48>"
"server.BaseHTTPHandler.handle_one_request : if len(self.raw_requestline) > 65536"
"server.BaseHTTPHandler.handle_one_request : if not self.raw_requestline"
"server.BaseHTTPHandler.handle_one_request : if not self.parse_request()"
"server.BaseHTTPHandler.handle_one_request : if not hassattr(self, mname)"
#My Handler Runs
"OAuthGrantRequestHandler : self.send_response"
127.0.0.1 - - [27/Aug/2018 14:35:18] "GET /favicon.ico HTTP/1.1" 200 -
Request handler completed
#My Handler Finishes

"server.BaseHTTPHandler.handle_one_request : flushing wfile to socket finishing request"
"socketserver.BaseRequestHandler.__init__ : self.finish()"
"socketserver.StreamRequestHandler.finish : "
"socketserver.BaseServer.process_request : self.shutdown_request"
service_action started
service_action complete
"socketserver.BaseServer.serve_forever : self._handle_request_noblock()"
"socketserver.BaseServer._handle_request_noblock : self.get_request()"
"socketserver.BaseServer._handle_noblock_request : self.process_request()"
"socketserver.BaseServer.process_request : self.finish_request()"
"socketserver.BaseServer.finish_request : self.RequestHandlerClass(request, client_address, self) #  request == <socket.socket fd=2008, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 57506)>,  client_address == ('127.0.0.1', 57506),  self == <MDGCoreLib.Utilities.HttpServer.Server.Server object at 0x0000026304E3FC88>"
"socketserver.BaseRequestHandler.__init__ : set self.client_address"
"socketserver.BaseRequestHandler.__init__ : set self.server"
"socketserver.BaseRequestHandler.__init__ : setup()"
"socketserver.StreamRequestHandler.setup : self.connection = self.request"
"socketserver.BaseRequestHandler.__init__ : self.handle()"
"server.BaseHttpRequestHandler.handle  : self.close_connection = True"
"server.BaseHTTPServer.handle_one_request : self.raw_requestline = self.rfile.readline(65537)"
"socket.readinto : self._checkClosed()"
"socket.readinto : return self._sock.recv_into(b)  #b == <memory at 0x0000026304E38C48>"
The program '[54321] Python @ tcp://localhost:55098/?legacyUnitTest' has exited with code -1 (0xffffffff).

以上是运行“ serve_forever()”方法的线程的所有内容,您可以看到父线程正在等待加入,输出结果为Parent thread : joining Thread 2。我的处理程序在输出为"OAuthGrantRequestHandler : self.send_response"时遇到并完成了两次,并且 Request handler completed:但是在尝试处理最后一个请求时,内部python库在socket.readinto : return self._sock.recv_into(b)挂起之前再也不会被调用。

任何人以前都曾遇到过这种Python挂断,而且周围还有吗?我有点无所适从,因为它挂在遇到我的处理程序/代码的server_forever()循环之间。

更新1 因此,将提琴手的痕迹与HTTPServer中的请求进行比较,我看到只有两个HTTPRequest,但是HTTPServer.serve_forever()尝试读取挂起的第三个请求。我还验证了(您可以在上面的输出中看到它)正在调用“ shutdown_request()”方法和基础方法来关闭套接字。那么,为什么serve_forever循环为什么继续通过下面的检查并在未收到新请求的情况下调用self._handle_request_noblock()呢?

ready = selector.select(poll_interval)
                    if ready:
                        self._handle_request_noblock()

1 个答案:

答案 0 :(得分:0)

几乎存在相同的问题,因此在深入研究socketserver.StreamRequestHandler实现之后,我发现了如何设置超时,以使那些错误的读取尝试最终可以解除阻塞。

    class MyRequestHandler(BaseHTTPRequestHandler):
        timeout = 2  # This is what makes the difference (seconds)

        def do_GET(self):
            ...
相关问题