我有一个非常基本的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()
答案 0 :(得分:0)
几乎存在相同的问题,因此在深入研究socketserver.StreamRequestHandler
实现之后,我发现了如何设置超时,以使那些错误的读取尝试最终可以解除阻塞。
class MyRequestHandler(BaseHTTPRequestHandler):
timeout = 2 # This is what makes the difference (seconds)
def do_GET(self):
...