21.22. http.server
— HTTP服务器¶
源代码: Lib/http/server.py
此模块定义用于实现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)¶ 此类基于
TCPServer
类构建,将服务器地址存储为名为server_name
和server_port
的实例变量。服务器可由处理程序访问,通常通过处理程序的server
实例变量。
HTTPServer
必须在实例化时给予 RequestHandlerClass,本模块提供三种不同的变体:
-
class
http.server.
BaseHTTPRequestHandler
(request, client_address, server)¶ 这个类用于处理到达服务器的HTTP请求。它本身不能响应任何实际的HTTP请求;它必须被子类化以处理每个请求方法(例如GET或POST)。
BaseHTTPRequestHandler
提供了许多类和实例变量,以及供子类使用的方法。处理程序将解析请求和头,然后调用特定于请求类型的方法。方法名称由请求构造。例如,对于请求方法
SPAM
,将调用没有参数的do_SPAM()
方法。所有相关信息存储在处理程序的实例变量中。子类不应该需要覆盖或扩展__init__()
方法。BaseHTTPRequestHandler
有以下实例变量:-
client_address
¶ 包含
(host, port)
形式的引用客户端地址的元组。
-
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
¶ io.BufferedIOBase
输入流,准备从可选输入数据的开始读取。
-
wfile
¶ 包含用于将响应写回客户端的输出流。在写入此流时,必须正确遵守HTTP协议。
在 3.6 版更改: 这是一个
io.BufferedIOBase
流。
BaseHTTPRequestHandler
具有以下属性:-
server_version
¶ 指定服务器软件版本。您可能想要覆盖此。格式是多个以空格分隔的字符串,其中每个字符串的格式名称为[/version]。例如,
'BaseHTTP/0.2'
。
-
sys_version
¶ 包含Python系统版本,以
version_string
方法和server_version
类变量可用的形式。例如,'Python/1.4'
。
-
error_message_format
¶ 指定
send_error()
方法应用于为客户端构建错误响应的格式字符串。默认情况下,字符串使用来自responses
的变量填充,这些变量基于传递给send_error()
的状态代码。
-
error_content_type
¶ 指定发送到客户端的错误响应的Content-Type HTTP头。默认值为
'text/html'
。
-
protocol_version
¶ 这指定在响应中使用的HTTP协议版本。如果设置为
'HTTP/1.1'
,服务器将允许HTTP持久连接;然而,您的服务器 must 然后在其对客户端的所有响应中包括精确的Content-Length
头(使用send_header()
)。为了向后兼容,设置默认为'HTTP/1.0'
。
-
MessageClass
¶ 指定一个
email.message.Message
-like类来解析HTTP头。通常,这不会被覆盖,它默认为http.client.HTTPMessage
。
-
responses
¶ 此属性包含错误代码整数到包含短和长消息的两元素元组的映射。例如,
{code: (shortmessage, longmessage)}
。 shortmessage 通常在错误响应中用作 message 密钥,longmessage 用作 explain 密钥。它由send_response_only()
和send_error()
方法使用。
BaseHTTPRequestHandler
实例具有以下方法:-
handle
()¶ 调用
handle_one_request()
一次(或,如果持续连接启用,多次)以处理传入的HTTP请求。你应该永远不需要覆盖它;而是实施适当的do_*()
方法。
-
handle_one_request
()¶ 此方法将解析并分派请求到适当的
do_*()
方法。你应该永远不需要重写它。
-
handle_expect_100
()¶ 当符合HTTP/1.1的服务器接收到
Expect: 100-continue
请求头时,它使用100 Continue
,然后是200 OK
头来响应。如果服务器不希望客户端继续,则可以覆盖此方法以引发错误。例如,服务器可以选择发送417 Expectation Failed
作为响应头和return False
。3.2 新版功能.
-
send_error
(code, message=None, explain=None)¶ 向客户端发送并记录完整的错误回复。数字 code 指定HTTP错误代码,以 message 作为错误的可选,简短,可读的描述。 explain 参数可用于提供有关错误的更详细信息;它将使用
error_message_format
属性格式化,并在一组完整的标题之后作为响应正文发出。responses
属性保存将在没有提供值时使用的 message 和 explain 的默认值;对于未知代码,两者的默认值为字符串???
。如果方法是HEAD或响应代码是以下之一,则主体将为空:1xx
,204 No Content
,205 Reset Content
,304 Not Modified
。在 3.4 版更改: 错误响应包括Content-Length头。添加了 explain 参数。
-
send_response
(code, message=None)¶ 向头缓冲区添加响应头,并记录接受的请求。 HTTP响应行写入内部缓冲区,然后是 Server 和 Date 头。这两个头的值分别从
version_string()
和date_time_string()
方法中选取。如果服务器不打算使用send_header()
方法发送任何其他头部,则send_response()
之后应该是end_headers()
调用。在 3.3 版更改: 标题存储到内部缓冲区,
end_headers()
需要显式调用。
-
send_header
(keyword, value)¶ 将HTTP头添加到内部缓冲区,当调用
end_headers()
或flush_headers()
时,将写入输出流。 keyword 应该指定header关键字,用 value 指定它的值。注意,在send_header调用完成后,必须调用end_headers()
以完成操作。在 3.2 版更改: 标题存储在内部缓冲区中。
-
send_response_only
(code, message=None)¶ 仅发送响应头,用于当服务器将
100 Continue
响应发送到客户端时的目的。头缓冲并直接发送输出流。如果没有指定 message,则发送对应于响应 code 的HTTP消息。3.2 新版功能.
-
end_headers
()¶ 在头缓冲区中添加一个空行(指示响应中HTTP头的结尾)并调用
flush_headers()
。在 3.2 版更改: 缓冲的头部被写入输出流。
-
flush_headers
()¶ 最后发送头到输出流和刷新内部头缓冲区。
3.3 新版功能.
-
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=None)¶ 返回由 timestamp (必须是
None
或time.time()
返回的格式)给出的为消息头格式化的日期和时间。如果省略 timestamp,则使用当前日期和时间。结果看起来像
'Sun, 06 Nov 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
,'File not found'
错误。否则,通过调用guess_type()
方法猜测内容类型,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
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
http.server
也可以使用带有 port number
参数的解释器的 -m
开关直接调用。与上一个示例类似,此文件相对于当前目录提供文件:
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
中的完全一样。注解
由
CGIHTTPRequestHandler
类运行的CGI脚本不能执行重定向(HTTP代码302),因为在执行CGI脚本之前发送代码200(随后的脚本输出)。这会优先处理状态代码。然而,类将运行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