http.serverHTTP服务器

源代码: Lib / http / server.py


这个模块定义了实现HTTP服务器的类(Web服务器).

警告

http.server不建议用于生产。它只实现了基本的安全检查.

一类,HTTPServer,是socketserver.TCPServersubclass.It在HTTP套接字上创建并侦听,将请求分派给ahandler。创建和运行服务器的代码如下所示:

def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):    server_address = ("", 8000)    httpd = server_class(server_address, handler_class)    httpd.serve_forever()
class http.server.HTTPServerserver_address, RequestHandlerClass

这个类基于TCPServerclass服务器地址存储为名为server_nameserver_port的实例变量。处理程序可以访问服务器,通常是通过处理程序的server实例变量

class http.server.ThreadingHTTPServer//(server_address, RequestHandlerClass)

此类与HTTPServer相同,但使用线程来处理请求,使用ThreadingMixIn。这对于处理Web浏览器预打开套接字非常有用,其中HTTPServer会无限期地等待.

版本3.7.

的新内容HTTPServerThreadingHTTPServer必须在实例化时给出RequestHandlerClass,本模块提供三种不同的变体:

class http.server.BaseHTTPRequestHandlerrequest, client_address, server

此类用于处理到达服务器的HTTP请求。它本身无法响应任何实际的HTTP请求;它必须是子类来处理每个请求方法(例如GET或POST).BaseHTTPRequestHandler提供了许多类和实例变量,以及子类使用的方法.

处理程序将解析请求和标题,然后调用特定于请求类型的方法。方法名称是根据请求构建的。例如,对于请求方法SPAM,将调用do_SPAM()方法,不带参数。所有相关信息都存储在处理程序的实例变量中。子类不需要覆盖或扩展__init__()方法.

BaseHTTPRequestHandler有以下实例变量:

client_address

包含一个形式为(host, port)的元组引用客户端’saddress.

server

包含服务器实例.

close_connection

应该在handle_one_request()返回之前设置的布尔值,指示是否可能需要另一个请求,或者是否应该关闭连接。

requestline

包含HTTP请求行的字符串表示形式。剥离终止CRLF。该属性应由handle_one_request()。如果没有处理有效的请求行,则应将其设置为空字符串.

command

包含命令(请求类型)。例如,"GET".

path

包含请求路径.

request_version

包含请求中的版本字符串。例如,"HTTP/1.0".

headers

包含MessageClassclassvariable。此实例解析和管理HTTPrequest中的标头。来自parse_headers()http.client函数用于解析头文件,它要求HTTP请求提供有效的RFC 2822 风格标题.

rfile

一个io.BufferedIOBase输入流,可以从可选输入数据的开头读取.

wfile

包含用于将响应写回客户端的输出流。在编写此流时必须使用正确的HTTP协议,以便与HTTPclients成功互操作.

版本3.6更改:这是io.BufferedIOBase stream.

BaseHTTPRequestHandler具有以下属性:

server_version

指定服务器软件版本。您可能想要覆盖它。格式是多个以空格分隔的字符串,其中每个字符串的格式为[/ version]。例如, "BaseHTTP/0.2".

sys_version

包含Python系统版本,以version_string方法和server_version classvariable可用的形式。例如,"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类似于解析HTTPheaders的类。通常,这不会被覆盖,并且默认为http.client.HTTPMessage.

responses

此属性包含错误代码整数到包含短消息和长消息的双元素元组的映射。例如, {code: (shortmessage,longmessage)}shortmessage通常用作响应中的message键,而longmessage作为explain键。它被send_response_only()send_error()方法使用

// BaseHTTPRequestHandler实例有以下几种方法:

handle

调用handle_one_request()一次(或者,如果多次启用持久连接)来处理传入的HTTP请求。你应该不必覆盖它;相反,实施适当的do_*()methods.

handle_one_request ()

这个方法将解析并发送请求到适当的do_*()方法。您永远不需要覆盖它.

handle_expect_100 ()

当HTTP / 1.1兼容服务器收到Expect: 100-continue请求标头时,它会回复一个100 Continue 其次是 200OK如果服务器不希望客户端继续,则可以重写此方法以引发错误。对于例如服务器可以选择发送417Expectation Failed作为响应头和return False.

新版本3.2.

send_errorcode, message=None, explain=None

向客户端发送并记录完整的错误回复。数字code指定HTTP错误代码,message作为错误的可选,简短,易读的描述。explain参数可用于提供有关错误的更详细信息;它将使用error_message_format属性进行格式化,并作为响应主体发出,后面是完整的标题集。responsesattribute保存messageexplain的默认值,如果没有提供值,将使用该值;对于未知代码,两者的默认值是字符串???。如果方法为HEAD或响应代码为以下之一,则正文将为空:1xx,204 No Content, 205 Reset Content, 304 Not Modified.

在版本3.4中更改:错误响应包含Content-Length头。添加explainargument.

send_response (code, message=None)

在header缓冲区中添加一个响应头并记录acceptrequest。HTTP响应行写入内部缓冲区,然后是ServerDate头。这两个标题的值分别从version_string()date_time_string()方法中获取。如果服务器没有使用send_header()方法发送任何其他头文件,那么send_response()应该跟着end_headers()呼叫。

改版3.3:标题存储在内部缓冲区和end_headers()需要明确调用.

send_headerkeyword, value

将HTTP标头添加到内部缓冲区,当end_headers()flush_headers()被调用时,该缓冲区将写入输出流。keyword应该用value指定其值。请注意,在完成send_header调用之后,必须调用end_headers()才能完成操作.

在版本3.2:标题存储在内部缓冲区中

send_response_onlycode, message=None)

仅发送响应头,用于100Continue响应由服务器发送到客户端。标头没有缓冲,直接发送输出流。如果没有指定message,则发送对应响应code的HTTP消息.

新版本3.2.

end_headers

在标题缓冲区中添加一个空行(表示响应中HTTP标题的结尾)并调用flush_headers().

在3.2版中更改:缓冲的标题写入输出流.

flush_headers)

最后将标题发送到输出流并刷新内部标题缓冲区。

版本3.3.

log_request(code=”-“, size=”-“)

新的接受(成功)请求。code应指定与响应关联的numericHTTP代码。如果响应的大小可用,那么它应该作为size参数传递

log_error// ()

当请求不能时报错实现。默认情况下,它将消息传递给log_message(),因此它采用相同的参数(format和附加值).

log_messageformat,

记录任意消息sys.stderr。通常会覆盖此选项以创建自定义错误日志记录机制。format参数是标准的printf样式格式字符串,其中log_message()被应用为格式的输入。clientip地址和当前日期和时间以每条记录的信息为前缀.

version_string ()

返回服务器软件的版本字符串。这是server_versionsys_versionattributes.

date_time_stringtimestamp=None

返回timestamp(必须是None或者以time.time())返回的格式,格式化为邮件头。如果省略timestamp,则使用当前日期和时间.

结果看起来像"Sun, 06 Nov 1994 08:49:37 GMT".

log_date_time_string

返回当前日期和时间,格式化为logging.

address_string()

返回客户端地址.

更改版本3.3:以前,执行了名称查找。为了避免名称解析延迟,它现在总是返回IP地址.

class http.server.SimpleHTTPRequestHandler (request, client_address, server, directory=None )

该类提供当前目录及以下文件,直接将目录结构映射到HTTP请求.

很多工作,比如解析请求,都是由基类完成的BaseHTTPRequestHandler。这个类实现了do_GET()do_HEAD()功能。

以下定义为SimpleHTTPRequestHandler

server_version

这将会 "SimpleHTTP/" + __version____version__在模块级定义.

extensions_map

字典映射后缀为MIME类型。默认由空字符串表示,并被认为是application/octet-stream。映射使用不区分大小写,因此只应包含较低的密钥.

directory

如果未指定,则要提供的目录是当前工作目录.

SimpleHTTPRequestHandlerclass定义了以下方法:

do_HEAD

这个方法服务于"HEAD"请求类型:它发送它为相应的//发送的头文件GET请求见do_GET()用于更完整解释可能标题的方法.

do_GET (

通过将请求解释为相对于当前工作目录的apath,将请求映射到本地文件.

如果请求被映射到目录,则检查目录是否为名为index.html的文件或者index.htm (以该顺序)。如果找到,则返回文件的内容;否则通过调用list_directory()方法生成目录列表。此方法使用os.listdir()扫描目录,如果404失败,则返回listdir()错误响应

如果请求被映射到文件,它打开了。打开所请求文件的任何OSError异常都映射到404,"File not found"错误。如果请求中有"If-Modified-Since"标题,并且在此时间之后文件未被修改,则会发送304, "Not Modified"响应。否则,通过调用guess_type()方法猜测内容类型,然后调用extensions_map变量,并返回文件内容.

A "Content-type:" header输出猜测的内容类型,然后输出一个"Content-Length:"标题文件的大小和"Last-Modified:"带有文件修改时间的标题

然后是一个空行,表示标题的结尾,然后输出文件的内容。如果文件的MIME类型以text/开头,则文件以文本模式打开;否则使用二进制模式.

例如用法,请参见test()模块中http.server functioninvocation的实现

在3.7版中更改:支持"If-Modified-Since" header.

SimpleHTTPRequestHandler类可以在下面的方式中使用,以创建一个非常基本的Web服务器,提供相对于当前目录的文件:

import http.serverimport socketserverPORT = 8000Handler = http.server.SimpleHTTPRequestHandlerwith socketserver.TCPServer(("", PORT), Handler) as httpd:    print("serving at port", PORT)    httpd.serve_forever()

http.server也可以使用带有-m参数的解释器的port number开关直接调用。与前面的示例类似,它提供相对于当前目录的文件:

python -m http.server 8000

默认情况下,服务器将自身绑定到所有接口。选项-b/--bind指定它应绑定的特定地址。例如,以下命令导致服务器仅绑定到localhost:

python -m http.server 8000 --bind 127.0.0.1

版本3.4中的新增内容:--bind参数介绍.

默认情况下,服务器使用当前目录。选项 -d/--directory指定应该为其提供文件的目录。例如,以下命令使用特定目录:

python -m http.server --directory /tmp/

版本3.7中新增:--directory指定备用目录

class http.server.CGIHTTPRequestHandlerrequest, client_address, server

此类用于从当前目录及以下提供CGI脚本的文件或输出。请注意,映射HTTP层次结构tolocal目录结构与SimpleHTTPRequestHandler.

注意

CGIHTTPRequestHandlerclass不能执行(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"请求类型,仅允许CGIscripts。尝试POST到非CGI url时输出错误501,“只能POST到CGI脚本”.

请注意,对于securityreasons,CGI脚本将使用用户nobody的UID运行。CGI脚本的问题将被转换为错误403.

CGIHTTPRequestHandler可以通过传递--cgi选项:

python -m http.server --cgi 8000