python standard library http.server

python 标准库之 http.server

今天下午主要是陪我闺女,组装完成一个桌面足球,很开心的一下午。

孩子的童年只有一次,有时间多陪陪孩子吧。

python 标准库 http.server

从python2时代开始 SimpleHttpServer就陪伴我走过那些快乐的时光。可以自己建立一个简单的文件服务器,让同事们通过浏览器就可以访问我电脑上的资源,而不需要http server或者 ftp软件。

到了python3时代,这个模块被合并进了http.server。

参考网址

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

HTTPServersocketserver.TCPServer 的一个子类。它会创建和侦听 HTTP 套接字,并将请求调度给处理程序。用于创建和运行服务器的代码看起来像这样

1
2
3
4
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_nameserver_port 的实例变量中。服务器可被处理程序通过 server 实例变量访问。

class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)

根据官方说明,这是一个基于 ThreadingMixIn的类,主要功能是使用线程处理请求。

实例变量

BaseHTTPRequestHandler has the following instance variables:

  • client_address

    包含指向客户地址的元组类型数据(host,port)

  • server

    包含Server实例

  • close_connection

    返回一个Boolean类型数据,在handle_one_request() ,表明另一个请求开始,或者当前请求关闭。

  • requestline

    包含http请求行,. 这个属性应该用 handle_one_request()设置. 如果一个不存在的请求被执行,应将其设置成空字符串。

  • command

    包含Http请求类型,例如:’Get’

  • path

    包含请求url路径

  • request_version

    包含请求的版本,例如:’ HTTP/1.0 ‘

  • headers

    包含通过MessageClass 类声明的变量。实例会转化为http请求。http.clientparse_headers() 方法可以验证一个非法的请求头,参照 RFC 2822 中请求头说明。

  • rfile

    一个io.BufferedIOBase 输入流对象,读取可能输入数据。

  • wfile

    根据客户端请求,返回数据

实例属性

实例方法

  • handle()

    调用handle_one_request() 方法一次(如果保持连接,会调用多次) 来管理http请求。. 此方法不需要重写,除此以外,可以重写 do_*() 等方法实现处理请求。

  • handle_one_request()

    此方法不需要重写,实现处理 do_*()等方法.

  • handle_expect_100()

    当 HTTP/1.1 请求时,服务器期望返回 100-continue 并返回 200响应码。如果想拒绝客户端连接,会抛出一个异常。

  • send_error(code, message=None, explain=None)

  • send_response(code, message=None)

  • send_header(keyword, value)

  • send_response_only(code, message=None)

  • end_headers()

  • flush_headers()

  • log_request(code=’-‘, size=’-‘)

  • log_error()

  • log_message(format, )

  • version_string()

  • date_time_string(timestamp=None)

  • log_date_time_string()

  • address_string()

创建一个简易服务器

例如下面的代码:

1
2
3
4
5
6
7
8
9
10
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()

当然也可以通过命令行方式创建,例如:

1
python -m http.server 8000

默认绑定本机的ip地址。

当然你可以指定一个ip地址,加入--bind参数

1
python -m http.server 8000 --bind 127.0.0.1

3.8 新增 支持绑定ipv6地址

3.7 新增支持绑定一个cgi程序,例如

1
python -m http.server --cgi 8000

一个具体应用的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python

from http.server import BaseHTTPRequestHandler, HTTPServer

# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):

# GET
def do_GET(self):
# Send response status code
self.send_response(200)

# Send headers
self.send_header('Content-type','text/html')
self.end_headers()

# Send message back to client
message = "Hello world!"
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return

def run():
print('starting server...')

# Server settings
# Choose port 8080, for port 80, which is normally used for a http server, you need root access
server_address = ('127.0.0.1', 8081)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()


run()

备注: 此处wfile.write方法 需要转成 byte类型,

可以参考stackoverflow上的关于这个问题的讨论::

python-3-x-basehttpserver-or-http-server

小结

看完http.server 深有感触,一个简单的服务器学习了这么多http协议实现,看来还得继续深入理解。

坚持原创技术分享,您的支持将鼓励我继续创作!