问题描述
我正在尝试创建一个简单的 HTTP 服务器,它使用继承 BaseHTTPServer 的 Python HTTPServer。 [https://github.com/python/cpython/blob/main/Lib/http/server.py][1]
网上有很多这种方法的例子,我认为我没有做任何不寻常的事情。
我只是通过以下方式导入类: “从 http.server 导入 HTTPServer,BaseHTTPRequestHandler” 在我的代码中。
我的代码覆盖了 do_GET() 方法来解析路径变量以确定要显示的页面。
但是,如果我启动此服务器并在本地连接到它(例如:http://127.0.0.1:50000),第一页加载正常。如果我导航到另一个页面(通过我的第一页链接)也可以正常工作,但是,有时(这有点零星),会出现延迟并且服务器日志显示请求超时: timeout('timed out' ) 错误。我已经追踪到 BaseHTTPServer 类中的 handle_one_request 方法:
def handle_one_request(self):
"""Handle a single HTTP request.
You normally don't need to override this method; see the class
__doc__ string for information on how to handle specific HTTP
commands such as GET and POST.
"""
try:
self.raw_requestline = self.rfile.readline(65537)
if len(self.raw_requestline) > 65536:
self.requestline = ''
self.request_version = ''
self.command = ''
self.send_error(HTTPStatus.REQUEST_URI_TOO_LONG)
return
if not self.raw_requestline:
self.close_connection = True
return
if not self.parse_request():
# An error code has been sent,just exit
return
mname = 'do_' + self.command ## the name of the method is created
if not hasattr(self,mname): ## checking that we have that method defined
self.send_error(
HTTPStatus.NOT_IMPLEMENTED,"Unsupported method (%r)" % self.command)
return
method = getattr(self,mname) ## getting that method
method() ## finally calling it
self.wfile.flush() #actually send the response if not already done.
except socket.timeout as e:
# a read or a write timed out. discard this connection
self.log_error("Request timed out: %r",e)
self.close_connection = True
return
您可以在“except socket.timeout as e:”子句中看到异常在哪里抛出。
我已尝试通过将其包含在我的代码中来覆盖此方法,但尚不清楚导致错误的原因,因此我陷入了死胡同。我尝试创建非常基本的 HTML 页面,以查看页面本身是否有内容,但即使是“空白”页面也会导致相同的偶发问题。
奇怪的是,有时页面会立即加载,而且几乎是随机加载的,然后会超时。有时是同一个页面,有时是不同的页面。
我玩过 http.timeout 设置,但没有区别。我怀疑这是一些潜在的套接字问题,但无法进一步诊断。
这是在运行 Big Sur 11.3.1 和 Python 版本 3.9.4 的 Mac 上运行的。
有关可能导致此超时的原因的任何想法,尤其是有关解决方案的任何建议。任何指针将不胜感激。
解决方法
经过进一步调查,这似乎是 Safari 的问题。运行完全相同的代码并使用 Firefox 不会显示相同的问题。