当您调用SocketServer.TCPServer 时,您将您的Handler 类指定为接收传入请求的类。
SimpleHTTPServer 模块为您提供的所有帮助只是提供了基本的 HTTP 功能,但您可以自己编写所有这些功能。
因此,正如您所说,当您定义 Handler 时,您将继承 SimpleHTTPRequestHandler 类的所有方法,但随后会覆盖两个预定义方法:do_GET 和 do_POST。您还可以覆盖类中的任何其他方法。
然而,如果不是SimpleHTTPRequestHandler 中定义的handle 方法,这些do_* 方法将永远 被调用,因为它是这个函数 em> 由socketserver 模块调用。
因此,如果您只是继承 socketserver.BaseRequestHandler,您将失去所有功能,因为此类的 handle() 方法什么都不做:
class socketserver.BaseRequestHandler
...
handle()
此功能必须完成服务于
要求。默认实现什么也不做。几个实例
属性可用;该请求可作为
自我请求;客户端地址为 self.client_address;和
服务器实例为 self.server,以防它需要访问每个服务器
信息。
...
因此,通过从 SimpleHTTPServer 模块导入 SimpleHTTPRequestHandler,您可以立即获得 HTTP 服务器的基本功能。
所有这些功能都记录在 here 中,并在其 handle 方法中有重要的一点:
class http.server.BaseHTTPRequestHandler(request, client_address, server)
...
handle()
调用 handle_one_request() 一次(或者,如果持久
多次启用连接)以处理传入的 HTTP
要求。您永远不需要覆盖它;相反,实施
适当的 do_*() 方法。
handle_one_request()
这个方法会解析并分发请求
到适当的 do_*() 方法。您永远不需要覆盖
它。
...
所以最后,在分解socketserver.TCPServer 将如何为您传递它的whatever 类调用handle() 方法之后,我们将看到SimpleHTTPRequestHandler 如何将请求传递到适当的do_GET、do_POST 或任何取决于请求标头的方法。
如果您想了解如何自己实现此功能,请查看/usr/lib/pythonX.Y/http/server.py 或GitHub 中的源代码。
我们可以在那里看到SimpleHTTPServer 继承了BaseHTTPServer 的内容,这就是handle() 和handle_one_request() 方法的定义:
因此,正如文档所述,handle 只是将请求传递给handle_one_request,直到连接关闭:
def handle(self):
"""Handle multiple requests if necessary."""
self.close_connection = True
self.handle_one_request()
while not self.close_connection:
self.handle_one_request()
handle_one_request 是调用 do_* 方法的地方:
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
(请注意,我对我的 cmets 进行了双重哈希 (##) 以将它们与原作者的分开)