0

我正在尝试创建一个简单的 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),则第一页加载正常。如果我导航到另一个也可以正常工作的页面(通过我的第一页链接),但是,有时(这有点零星),会有延迟并且服务器日志显示请求超时:超时('超时' ) 错误。我已将其追踪到 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 上。

关于可能导致此超时的任何想法,特别是关于解决方案的任何建议。任何指针将不胜感激。

4

1 回答 1

0

经过进一步调查,这似乎是 Safari 的一个问题。运行完全相同的代码并使用 Firefox 不会显示相同的问题。

于 2021-05-07T23:07:10.807 回答