http server-python 3.6.5文档翻译

原文地址:HTTP servers

本文档介绍的是实现HTTP server相关的类。

HTTPServer是socketserver.TCPServer的子类,它创建并监听一个HTTP socket,将请求分发给handler。创建并运行server的代码如下:

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地址(存储在名称为server_name和server_port的变量中)。这个类建立的server对于handler是可见的,handler有一个名称为server的变量指向它。

HTTPServer需要传入RequestHandlerClass作为参数,其有三个变体:

class http.server.BaseHTTPRequestHandler(request, client_address, server)

这个类可以处理发送到server的HTTP请求,它自己并不会响应任何HTTP请求,你需要在它的子类中处理这些请求。但是它提供了很多有用的类、变量和方法。在这个类中,它会解析请求和header,然后根据请求类型调用相应方法(这些方法的名称是由请求指定的,例如,请求中指定方法SPAM,对应的方法即为没有参数的do_SPAM()方法)。这个类中还保存了请求的相关信息。另外,子类不需要重写__init__()方法。

BaseHTTPRequestHandler包含以下变量:

  • client_address
    元组,(host,port),表示client地址
  • server
    表示server实例
  • close_connection
    boolean,表示是否接受其他的请求,即连接是否会在收到一个请求后关闭,此值应该在handle_one_request()方法返回前设置
  • requestline
    指HTTP请求的string内容。会去掉回车换行符。这个值通过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
    表示返回给client的响应的输出流。向此输出流写数据时必须符合HTTP协议

BaseHTTPRequestHandler包含以下属性:

  • server_version
    表示server的版本。你可以重写它,格式为多个空格分割的字符串,每个字符串为“name[/version]”形式,如 ‘BaseHTTP/0.2’
  • sys_version
    表示Python系统的版本,如’Python/1.4’
  • error_message_format
    表示错误信息的格式。send_error()方法会使用它格式化错误信息并将其发送给client。其默认值为基于response的状态码的字符串
  • error_content_type
    表示发送给client的错误响应的内容类型。默认值为’text/html’
  • protocol_version
    表示response的HTTP协议版本。如果设置为’HTTP/1.1’,那么server会允许长连接,但是server必须在每个响应中通过send_header()指定确切的头部信息:Content-Length。默认值为’HTTP/1.0’
  • MessageClass
    表示一个email.message.Message,其用于解析HTTP头信息。通常你不需要修改它,使用默认值http.client.HTTPMessage即可。
  • responses
    其包含错误码与错误信息的映射,错误信息为包含两个元素的元组。例如{code: (shortmessage, longmessage)}。其中,shortmessage通常用来表示错误信息的message key,longmessage表示explain key。这个属性会被send_response_only()和send_error()使用

BaseHTTPRequestHandler包含以下方法:

  • handle()
    调用handle_one_request()处理传入的HTTP请求(如果是长连接,可以调用多次,否则只需调用一次)。你不应该重写这个方法,只需要实现适当的do_*()方法即可
  • handle_one_request()
    这个方法会解析并分发请求到相应的do_*()方法。你不应该重写这个方法
  • handle_expect_100()
    当支持HTTP/1.1的server收到Expect: 100-continue的请求头时,它会返回一个100 Continue和200 OK。如果server不希望client能够continue,可以重写这个方法,返回一个异常。例如,sever可以返回417 Expectation Failed作为响应
  • send_error(code, message=None, explain=None)
    发送错误信息给client。其参数code表示HTTP错误码,message表示简短的错误描述,explain表示错误的相关信息。explain会被error_message_format格式化,然后添加到组装完成的头信息后面,作为响应的body。如果未指定message和explain,此方法会使用responses属性指定的值,对于responses属性中没有的code,默认message和explain为“???”。如果方法为HEAD那么body会为空。如果响应码为1xx, 204 No Content, 205 Reset Content, 304 Not Modified,body也为空
  • send_response(code, message=None)
    向header buffer添加响应头信息。HTTP响应会写入内部buffer,后面是Server和Date头信息(这两个信息通过version_string()和date_time_string()方法获得)。如果server不使用send_header()发送头信息,那么在send_response()后需要调用end_headers()
  • send_header(keyword, value)
    向内部buffer添加HTTP头信息。当调用end_headers()或者flush_headers()时,添加到内部buffer的HTTP头信息会被写到输出流。注意,在调用send_header后必须调用end_headers()
  • send_response_only(code, message=None)
    仅发送response头信息,当server向client发送100 Continue时使用。头信息不会立刻缓存并发送到输出流。如果message未指定,那么将会发送code对应的HTTP信息
  • end_headers()
    向头信息buffer添加一个空行,以指明response的HTTP头信息已结束,然后会调用flush_headers()
  • flush_headers()
    将头信息发送到输出流,并刷新内部头信息buffer
  • log_request(code=’-‘, size=’-‘)
    日志输出进入的请求
  • log_error(…)
  • log_message(format, …)
  • version_string()
    返回server的版本信息,包括server_version和sys_version
  • date_time_string(timestamp=None)
    返回指定的时间戳,如果为空,那么将使用当前时间。示例:’Sun, 06 Nov 1994 08:49:37 GMT’
  • log_date_time_string()
  • address_string()
    返回client地址

class http.server.SimpleHTTPRequestHandler(request, client_address, server)

这个类用于从当前目录及子目录提供文件,会将目录结构映射到HTTP request。

很多工作,如解析request,已经在BaseHTTPRequestHandler中完成了。本类则实现了do_GET()和do_HEAD()方法。

SimpleHTTPRequestHandler的类级属性如下:

  • server_version
    格式为"SimpleHTTP/" + __version__,其中__version__定义在module级
  • extensions_map
    表示MIME类型与后缀映射的字典。默认值为空,表示“application/octet-stream”。这个映射是大小写不敏感的,所以key请使用小写

SimpleHTTPRequestHandler的方法如下:

  • do_HEAD()
    这个方法会处理‘HEAD’请求。它发送的头信息与“GET”请求一样,在do_GET()可以看到更多的头信息相关内容
  • do_GET()
    请求会被映射为本地目录。它会将请求解析为表示当前工作目录的地址。
    当请求映射到某个地址时,会在这个地址寻找“index.html”或“index.htm”文件。如果找到了,会返回找到的文件;如果没找到,会调用list_directory()方法列举当前目录(list_directory()方法使用os.listdir()方法扫描当前目录,如果listdir()失败,会返回错误码404)。
    如果请求映射的是文件,那么会打开这个文件并返回。如果在打开过程中出现“OSError”,会返回“404, ‘File not found’”。如果打开文件成功,那么会通过guess_type()方法查找文件类型(通过extensions_map查找)。
    返回的头信息包括:“Content-type:”表示文件类型,“Content-Length:”表示文件大小,“Last-Modified:”表示最后修改时间。
    然后加一个空行表示头信息结束,之后提交到输出流。如果文件的MIME类型以“text/”开头,那么作为文本打开,否则作为二进制文件打开。
    使用示例请看http.server的test()部分

下面的代码使用SimpleHTTPRequestHandler实现了一个非常简单的webserver:

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也可以通过解释器执行:

python -m http.server 8000

默认情况下,server会绑定到所有接口。通过-b/--bind可以指定绑定到哪个接口。例如,下列代码会让server绑定到localhost:

python -m http.server 8000 --bind 127.0.0.1

class http.server.CGIHTTPRequestHandler(request, client_address, server)

这个类支持文件输出和CGI接口输出。对于文件输出,它的文件结构与HTTP结构的映射方式,跟SimpleHTTPRequestHandler是完全一样的。

注意:CGIHTTPRequestHandler运行的CGI脚本不支持重定向(返回HTTP code 302),因为每次访问CGI脚本都会发送200,会重置状态码

然而,如果请求被认为是访问CGI脚本,那么就不会以文件的方式访问它,而是以CGI脚本的方式访问。仅支持基于目录的CGI脚本,其他的server配置会将特殊扩展视为某种CGI脚本。

如果请求链接到cgi_directories路径下,那么do_GET()和do_HEAD()将会被修改为CGI脚本的形式为output提供服务,而不是以文件的方式提供服务。

CGIHTTPRequestHandler提供以下数据成员:

  • cgi_directories
    默认为['/cgi-bin', '/htbin'],表示以CGI脚本方式提供服务的目录

CGIHTTPRequestHandler提供以下方法:

  • do_POST()
    这个方法对应于“POST”请求,仅应用与CGI脚本。如果通过POST方式访问非CGI目录,那么会返回错误码501,“Can only POST to CGI scripts”

注意:出于安全性考虑,CGI脚本运行时会与用户UID绑定。CGI脚本如果发生错误会抛出错误码403。

CGIHTTPRequestHandler可以使用命令行启动:

python -m http.server --cgi 8000
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值