20.18. BaseHTTPServer — 基本 HTTP 服务器 — Python 文档
20.18. 基础HTTP服务器 — 基本的 HTTP 服务器
源代码: :source:`Lib/BaseHTTPServer.py`
该模块定义了两个用于实现 HTTP 服务器(Web 服务器)的类。 通常,该模块不直接使用,而是用作构建功能性 Web 服务器的基础。 请参阅 SimpleHTTPServer 和 CGIHTTPServer 模块。
第一个类 HTTPServer 是 SocketServer.TCPServer 子类,因此实现了 SocketServer.BaseServer 接口。 它创建并侦听 HTTP 套接字,将请求分派给处理程序。 创建和运行服务器的代码如下所示:
def run(server_class=BaseHTTPServer.HTTPServer,
handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
- class BaseHTTPServer.HTTPServer(server_address, RequestHandlerClass)
- 该类基于
TCPServer
类构建,将服务器地址存储为名为server_name
和server_port
的实例变量。 服务器可由处理程序访问,通常通过处理程序的server
实例变量。
- class BaseHTTPServer.BaseHTTPRequestHandler(request, client_address, server)
该类用于处理到达服务器的 HTTP 请求。 它本身无法响应任何实际的 HTTP 请求; 它必须被子类化以处理每个请求方法(例如 获取或发布)。 BaseHTTPRequestHandler 提供了许多类和实例变量,以及供子类使用的方法。
处理程序将解析请求和标头,然后调用特定于请求类型的方法。 方法名称是根据请求构造的。 例如,对于请求方法
SPAM
,将不带参数调用do_SPAM()
方法。 所有相关信息都存储在处理程序的实例变量中。 子类不需要覆盖或扩展__init__()
方法。BaseHTTPRequestHandler 有以下实例变量:
- client_address
包含一个
(host, port)
形式的元组,引用客户端的地址。
- server
包含服务器实例。
- command
包含命令(请求类型)。 例如,
'GET'
。
- path
包含请求路径。
- request_version
包含来自请求的版本字符串。 例如,
'HTTP/1.0'
。
- headers
保存由 MessageClass 类变量指定的类的实例。 此实例解析和管理 HTTP 请求中的标头。
- rfile
包含一个输入流,位于可选输入数据的开头。
- wfile
包含用于将响应写回客户端的输出流。 写入此流时必须正确遵守 HTTP 协议。
BaseHTTPRequestHandler 有以下类变量:
- server_version
指定服务器软件版本。 您可能想要覆盖它。 格式为多个以空格分隔的字符串,其中每个字符串的格式为 name[/version]。 例如,
'BaseHTTP/0.2'
。
- sys_version
包含 Python 系统版本,采用 version_string 方法和 server_version 类变量可用的形式。 例如,
'Python/1.4'
。
- error_message_format
指定用于构建对客户端的错误响应的格式字符串。 它使用带括号的键控格式说明符,因此格式操作数必须是字典。 code 键应该是一个整数,指定数字 HTTP 错误代码值。 message 应该是一个包含发生了什么的(详细)错误消息的字符串,而 explain 应该是错误代码编号的解释。 默认 message 和 explain 值可以在 responses 类变量中找到。
- error_content_type
指定发送到客户端的错误响应的 Content-Type HTTP 标头。 默认值为
'text/html'
。2.6 版新增: 以前,内容类型始终为
'text/html'
。
- protocol_version
这指定了响应中使用的 HTTP 协议版本。 如果设置为
'HTTP/1.1'
,服务器将允许HTTP长连接; 但是,您的服务器 必须 然后在其对客户端的所有响应中包含准确的Content-Length
标头(使用 send_header())。 为了向后兼容,设置默认为'HTTP/1.0'
。
- MessageClass
指定一个 rfc822.Message 之类的类来解析 HTTP 标头。 通常,这不会被覆盖,并且默认为 mimetools.Message。
- responses
此变量包含错误代码整数到包含短消息和长消息的二元素元组的映射。 例如,
{code: (shortmessage, longmessage)}
。 shortmessage通常用作错误响应中的message键,longmessage用作explain键(参见 error_message_format 类变量)。
BaseHTTPRequestHandler 实例具有以下方法:
- handle()
调用 handle_one_request() 一次(或者,如果启用了持久连接,则调用多次)来处理传入的 HTTP 请求。 你永远不需要覆盖它; 相反,实施适当的
do_*()
方法。
- handle_one_request()
此方法将解析请求并将其分派到适当的
do_*()
方法。 您永远不需要覆盖它。
- send_error(code[, message])
向客户端发送并记录完整的错误回复。 数字 code 指定 HTTP 错误代码,message 作为可选的更具体的文本。 发送一组完整的标头,然后是使用 error_message_format 类变量组成的文本。 如果方法为 HEAD 或响应代码为以下之一,则正文将为空:
1xx
、204 No Content
、205 Reset Content
、304 Not Modified
。
- send_response(code[, message])
发送响应头并记录接受的请求。 发送 HTTP 响应行,然后是 Server 和 Date 标头。 这两个标头的值分别从 version_string() 和 date_time_string() 方法中获取。
- send_header(keyword, value)
将特定的 HTTP 标头写入输出流。 keyword 应指定标题关键字,value 指定其值。
- end_headers()
发送一个空行,指示响应中 HTTP 标头的结尾。
- log_request([code[, size]])
记录已接受(成功)的请求。 code 应指定与响应关联的数字 HTTP 代码。 如果响应的大小可用,则应将其作为 size 参数传递。
- log_error(...)
无法满足请求时记录错误。 默认情况下,它将消息传递给 log_message(),因此它采用相同的参数(format 和其他值)。
- log_message(format, ...)
将任意消息记录到
sys.stderr
。 这通常会被覆盖以创建自定义错误日志记录机制。 format 参数是标准的 printf 样式格式字符串,其中 log_message() 的附加参数用作格式的输入。 客户端 IP 地址和当前日期和时间是记录的每条消息的前缀。
- version_string()
返回服务器软件的版本字符串。 这是 server_version 和 sys_version 类变量的组合。
- date_time_string([timestamp])
返回 timestamp 给出的日期和时间(必须采用 time.time() 返回的格式),格式为消息头。 如果省略 timestamp,则使用当前日期和时间。
结果看起来像
'Sun, 06 Nov 1994 08:49:37 GMT'
。2.5 版新增:时间戳参数。
- log_date_time_string()
返回当前日期和时间,格式用于记录。
- address_string()
返回客户端地址,格式化用于日志记录。 在客户端的 IP 地址上执行名称查找。
20.18.1。 更多例子
创建一个不会永远运行但直到满足某些条件的服务器:
def run_while_true(server_class=BaseHTTPServer.HTTPServer,
handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
"""
This assumes that keep_running() is a function of no arguments which
is tested initially and after each request. If its return value
is true, the server continues.
"""
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
while keep_running():
httpd.handle_request()