请求超时:Python 的 HTTPServer 中的 timeout('timed out')

问题描述

我正在尝试创建一个简单的 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 不会显示相同的问题。