http.server源码阅读
上一章讲SocketServer模块,它将服务端根据监听套接字和连接套接字分为了2个部分(BaseServer/BaseRequestHandler),而连接套接字类的处理方法相当简单,最终是一个handle函数就搞定了。http.server这个模块主要类BaseHTTPRequestHandle继承自BaseRequestHandle,对handle进行了一点点的加强,主要就是对http协议进行了简单的解析工作(源码版本Python3.5)
先上图为敬:D
这个模块只需要关心BaseHTTPRequestHandler类,其实里面还有个CGI处理类,不过这玩意儿估计也是上古神兽了。没关注的必要。
代码解读
- 支持http版本0.9、1.0、1.1,区别就是0.9版本只有body。1.1版本显式支持keep-alive。为了支持keep-alive,代码中有多处处理逻辑
- 对于内容的解析主要是使用parse_request方法。该方法逻辑主要解析第一行request line。如果出错就直接调用send_error返回错误内容。header部分主要引入了email.parser.Parser进行解析
- parser_request对
Except:100-continue
进行了特殊处理,见附录 - 返回status line和header是先使用send_response_only创建一个列表,然后调用send_header依次在列表中添加数据,最后调用end_headers发送数据
send_error函数就是一个回复的典范
- 剩下就是日志函数和几个辅助函数了
示例
1 | from http.server import BaseHTTPRequestHandler |
这是一个最简的http server。do_GET函数表面send_error就能够响应一个请求。do_POST函数参照send_error的逻辑只不过读取了客户端发送的body字段
小知识
类变量和实例变量
这2个非常相近,具体区别我就不概述了。在写代码的时候很多人无脑self.xxx = xxx就搞了一个实例变量。大多数时候用实例变量都能够替代类变量的功能。这很容易让人忽略类变量的优点。①含义明确:这是这个类的所有实例共用的。②不需要重载__init__,这在继承的时候是很有用哒~~~,so,不要有事没事无脑在__init__里面self.xxx = xxx啦