21.22. http.server
— HTTP 服务器¶
此模块定义用于实现HTTP服务器(Web服务器)的类。
HTTPServer
是 socketserver.TCPServer
的子类。它创建并监听了HTTP套接字,同时提交了请求。用以下方式可运行一个服务器:
def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
server_address = ('', 8000)
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
- class
http.server.
HTTPServer
(server_address, RequestHandlerClass)¶ 此类通过将服务器地址存储为名为
server_name
和server_port
的实例变量,在TCPServer
类上构建。服务器可由处理程序访问,通常通过处理程序的服务器
实例变量。
必须为HTTPServer
提供一个RequestHandlerClass实例化,本模块提供三种不同的变体:
- class
http.server.
BaseHTTPRequestHandler
(request, client_address, server)¶ 此类用于处理到达服务器的HTTP请求。它本身不能响应任何实际的HTTP请求;它必须被子类化以处理每个请求方法(例如,GET或POST)。
BaseHTTPRequestHandler
提供了许多类和实例变量,以及供子类使用的方法。处理程序将解析请求和头,然后调用特定于请求类型的方法。方法名称由请求构造。例如,对于请求方法
SPAM
,将调用不带参数的do_SPAM()
方法。所有相关信息存储在处理程序的实例变量中。子类不应该覆盖或扩展__init__()
方法。BaseHTTPRequestHandler
具有以下实例变量:-
client_address
¶ 包含引用客户端地址的
(主机, 端口)
形式的元组。
-
server
¶ 包含服务器实例。
-
close_connection
¶ 应在
handle_one_request()
返回之前设置的布尔值,指示是否可能需要另一个请求,或者是否应关闭连接。
-
requestline
¶ 包含HTTP请求行的字符串表示形式。终止CRLF被剥离。此属性应由
handle_one_request()
设置。如果没有处理有效的请求行,则应将其设置为空字符串。
-
command
¶ 包含命令(请求类型)。例如,
'GET'
。
-
path
¶ 包含请求路径。
-
request_version
¶ 包含请求中的版本字符串。例如,
'HTTP/1.0'
。
-
headers
¶ 保存由
MessageClass
类变量指定的类的实例。本实例解析和管理HTTP请求中的头。来自http.client
的parse_headers()
函数用于解析标头,并且它要求HTTP请求提供有效的 RFC 2822样式标题。
-
rfile
¶ 包含一个输入流,位于可选输入数据的开头。
-
wfile
¶ 包含用于将响应写回客户端的输出流。在写入此流时,必须正确遵守HTTP协议。
BaseHTTPRequestHandler
具有以下属性:-
server_version
¶ 指定服务器软件版本。您可能想要覆盖此。格式是多个以空格分隔的字符串,其中每个字符串的格式名称为[/ version]。例如,
'BaseHTTP/0.2'
。
-
sys_version
¶ 包含可由
version_string
方法和server_version
类变量使用的Python系统版本。例如,'Python/1.4'
。
-
error_message_format
¶ 指定由
send_error()
方法使用的格式字符串,用于为客户端构建错误响应。默认情况下,根据传递到send_error()
的状态代码,从responses
的变量填充字符串。
-
error_content_type
¶ 指定发送到客户端的错误响应的Content-Type HTTP头。默认值为
'text/html'
。
-
protocol_version
¶ 这指定在响应中使用的HTTP协议版本。如果设置为
'HTTP/1.1'
,则服务器将允许HTTP持久连接;然而,您的服务器必须在其对客户端的所有响应中包含准确的Content-Length
标头(使用send_header()
)。为了向后兼容,该设置默认为'HTTP/1.0'
。
-
MessageClass
¶ 指定
email.message.Message
类来解析HTTP标头。通常,这不会被覆盖,它默认为http.client.HTTPMessage
。
-
responses
¶ 此属性包含错误代码整数到包含短和长消息的两元素元组的映射。例如,
{code: (shortmessage, longmessage)}
。短消息通常用作错误响应中的消息键,longmessage作为说明键。它由send_response_only()
和send_error()
方法使用。
A
BaseHTTPRequestHandler
实例具有以下方法:-
handle
()¶ 调用
handle_one_request()
一次(如果启用持久连接,则多次)以处理传入的HTTP请求。你应该永远不需要覆盖它;而是实现适当的do_*()
方法。
-
handle_one_request
()¶ 此方法将解析并分派请求到适当的
do_*()
方法。你应该永远不需要重写它。
-
handle_expect_100
()¶ 当符合HTTP / 1.1标准的服务器接收到
期望: 100-继续
请求头时,会以/ t4> 继续
,然后按200 确定
如果服务器不希望客户端继续,则可以覆盖此方法以引发错误。例如,服务器可以选择发送417 期望 失败
作为响应标头和t5> False
。版本3.2中的新功能。
-
send_error
(code, message=None, explain=None)¶ 向客户端发送并记录完整的错误回复。数字代码指定HTTP错误代码,其中消息是可选的,简短的,可读的错误描述。explain参数可用于提供有关错误的更详细信息;它将使用
error_message_format
属性格式化,并在一组完整的标题后作为响应正文发出。responses
属性保存消息和说明的默认值,如果未提供值,将使用该值;对于未知代码,两者的默认值是字符串???
。如果方法为HEAD或响应代码为以下之一,则正文将为空:1xx
,204 否 内容
,205 重置 内容
,304 不是 修改
。在版本3.4中更改:错误响应包含Content-Length标头。添加了explain参数。
-
send_response
(code, message=None)¶ 向头缓冲区添加响应头,并记录接受的请求。HTTP响应行写入内部缓冲区,随后是服务器和日期标题。这两个头的值分别从
version_string()
和date_time_string()
方法中选取。如果服务器不打算使用send_header()
方法发送任何其他头,则send_response()
后应紧跟一个end_headers()
在版本3.3中更改:标题存储到内部缓冲区,
end_headers()
需要显式调用。
-
send_header
(keyword, value)¶ 将HTTP头添加到内部缓冲区,当调用
end_headers()
或flush_headers()
时,将写入输出流。关键字应指定标题关键字,值指定其值。注意,在send_header调用完成后,必须调用end_headers()
才能完成操作。在版本3.2中更改:标题存储在内部缓冲区中。
-
send_response_only
(code, message=None)¶ 仅发送响应头,用于在服务器向客户端发送
100 继续
响应时的目的。标头未缓冲并直接发送输出流。如果未指定消息,则发送与响应代码相对应的HTTP消息。版本3.2中的新功能。
-
end_headers
()¶ 在标头缓冲区中添加一个空行(表示响应中HTTP头的结尾)并调用
flush_headers()
。在版本3.2中更改:缓冲的标头写入输出流。
-
flush_headers
()¶ 最后发送头到输出流和刷新内部头缓冲区。
版本3.3中的新功能。
-
log_request
(code='-', size='-')¶ 记录接受(成功)请求。代码应指定与响应相关联的数字HTTP代码。如果响应的大小可用,则应将其作为size参数传递。
-
log_error
(...)¶ 在无法满足请求时记录错误。默认情况下,它将消息传递到
log_message()
,因此它采用相同的参数(格式和其他值)。
-
log_message
(format, ...)¶ 将任意消息记录到
sys.stderr
。这通常被覆盖以创建自定义错误日志记录机制。格式参数是标准的printf样式格式字符串,其中log_message()
的附加参数将作为格式化的输入应用。客户端IP地址和当前日期和时间以每个记录的消息为前缀。
-
version_string
()¶ 返回服务器软件的版本字符串。这是
server_version
和sys_version
属性的组合。
-
date_time_string
(timestamp=None)¶ 返回由消息头格式化的timestamp(必须为无或以
time.time()
返回的格式)给出的日期和时间。如果省略timestamp,则使用当前日期和时间。结果如
'Sun, 06 11月 1994 08:49:37 GMT'
。
-
log_date_time_string
()¶ 返回当前日期和时间,格式为日志记录。
-
address_string
()¶ 返回客户端地址。
在版本3.3中更改:以前,执行了名称查找。为了避免名称解析延迟,它现在总是返回IP地址。
-
- class
http.server.
SimpleHTTPRequestHandler
(request, client_address, server)¶ 此类提供来自当前目录及其以下的文件,直接将目录结构映射到HTTP请求。
很多工作,例如解析请求,由基类
BaseHTTPRequestHandler
完成。此类实现do_GET()
和do_HEAD()
函数。以下定义为
SimpleHTTPRequestHandler
的类级属性:-
server_version
¶ 这将是
“SimpleHTTP /” + __ version __
,其中__version__
模块级。
-
extensions_map
¶ 将后缀映射到MIME类型的字典。默认值由空字符串表示,并被认为是
application/octet-stream
。映射使用不区分大小写,因此应仅包含低位密钥。
SimpleHTTPRequestHandler
类定义以下方法:-
do_GET
()¶ 通过将请求解释为相对于当前工作目录的路径,将请求映射到本地文件。
如果请求映射到目录,将检查目录中是否存在名为
index.html
或index.htm
的文件(按此顺序)。如果找到,则返回文件的内容;否则通过调用list_directory()
方法生成目录列表。此方法使用os.listdir()
扫描目录,如果listdir()
失败,则会返回404
错误响应。如果请求映射到文件,则会打开它并返回内容。任何打开请求文件的
OSError
异常映射到404
,'文件 ,而不是 找到'
错误。否则,通过调用guess_type()
方法猜测内容类型,该方法依次使用extensions_map变量。输出具有猜测的内容类型的
'Content-type:'
报头,随后是具有文件大小的'Content-Length:'
报头和'Last-Modified:'
头文件的修改时间。然后跟随一个空行,表示头的结尾,然后输出文件的内容。如果文件的MIME类型以
text/
开头,则文本以文本模式打开;否则使用二进制模式。例如,使用,请参阅
http.server
模块中test()
函数调用的实现。
-
SimpleHTTPRequestHandler
类可以按照以下方式使用,以便创建一个非常基本的web服务器来提供相对于当前目录的文件:
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
还可以使用解释器的-m
开关和端口号
t>直接调用http.server
t8>参数。与上一个示例类似,此示例提供相对于当前目录的文件:
python -m http.server 8000
默认情况下,服务器将自身绑定到所有接口。选项-b/--bind
指定其应绑定的特定地址。例如,以下命令使服务器仅绑定到localhost:
python -m http.server 8000 --bind 127.0.0.1
版本3.4中新增: --bind
参数。
- class
http.server.
CGIHTTPRequestHandler
(request, client_address, server)¶ 这个类用于从当前目录和下面的文件或CGI脚本的输出。请注意,将HTTP层次结构映射到本地目录结构与在
SimpleHTTPRequestHandler
中的完全一样。注意
由于在执行CGI脚本之前发送代码200(随后的脚本输出),由
CGIHTTPRequestHandler
类运行的CGI脚本不能执行重定向(HTTP代码302)。这将抢占状态代码。然而,类将运行CGI脚本,而不是将其作为文件,如果它猜测它是一个CGI脚本。仅使用基于目录的CGI - 其他常见的服务器配置是将特殊扩展视为表示CGI脚本。
修改
do_GET()
和do_HEAD()
函数以运行CGI脚本并提供输出,而不是提供文件,如果请求导向cgi_directories
路径。CGIHTTPRequestHandler
定义以下数据成员:-
cgi_directories
¶ 这默认为
['/ cgi-bin', '/ htbin']
,并描述要作为包含CGI脚本的目录。
CGIHTTPRequestHandler
定义以下方法:-
do_POST
()¶ 此方法提供
'POST'
请求类型,仅适用于CGI脚本。错误501,“只能发送到CGI脚本”,当尝试POST到非CGI URL时输出。
注意,出于安全原因,CGI脚本将以用户nobody的UID运行。CGI脚本的问题将被转换为错误403。
-
可以通过传递--cgi
选项在命令行中启用CGIHTTPRequestHandler
:
python -m http.server --cgi 8000