Django源码分析系列之Wsgi协议介绍

原创
2018/07/02 00:32
阅读数 16
Web请求在服务端的最简流程

客户端 服务端 解析request 业务逻辑 响应response 响应客户端

通过这个流程我们可以发现, 在服务端,不管后端是什么Web服务器都要经历解析request(从socket数据包中解析请求)和响应response(把Python对象变成socket数据包)两个过程

而且这两个步骤对于所有请求都是一样的, 开始先从socket里面获取的数据包根据http协议把数据转换成python对象, 最后将响应的数据转换成bytes通过socket发送

于是Python中就抽象出了一个通用的WSGI接口, 对应请求的解析和序列化操作,由这个接口来统一处理,而Django/Flask等Web server只服务对应的框架和业务逻辑的处理,如下图

客户端 WSGI 业务逻辑 WSGI

业务逻辑就是我们的Django服务器WSGI(全称Web Server Gateway Interface)Web服务器网关接口是Python语言定义Web服务器(Nginx/Apache)和Web应用程序(Django/Flask)之间的一种接口

实现一个简单的WebServer

from wsgiref import simple_server


# 定义Wsgi服务器
class WsgiServer(simple_server.WSGIServer):

pass


# 实现Wsgi应用服务调用, 负责将处理结果写会到socket, 返回给客户端
class ServerHandler(simple_server.ServerHandler):

pass


# Wsgi请求的处理方法
class WsgiRequestHandler(simple_server.WSGIRequestHandler):

def get_environ(self):
for k, v in self.headers.items():
if '_' in k:
del self.headers[k]
return super().get_environ()

def handle(self):
self.raw_requestline = self.rfile.readline(65537)
if len(self.raw_requestline) > 65536:
self.send_error(411)
return
if not self.parse_request():
return
# 当我们解析http请求完成后, 就调用ServerHandler函数来调用我们的应用程序来实现业务逻辑的处理
handler = ServerHandler(
self.rfile, self.wfile, self.get_stderr(), self.get_environ()
)
handler.request_handler = self
handler.run(self.server.get_app())


def wsgi_handle(environment, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
return [b"Hello World"]


def run(addr, port, wsgi_handler, server_cls=simple_server.WSGIServer):
server_address = (addr, port)
httpd = server_cls(server_address, WsgiRequestHandler)
httpd.set_app(wsgi_handler)
httpd.serve_forever()


def main():
run('0.0.0.0', 8080, wsgi_handle,)


if __name__ == "__main__":
main()

通过上面的简单服务器的实现, 可以看到WSGI服务器主要分为三个部分:WsgiServer、WsgiRequestHandler、ServerHandler三个部分,WsgiServer接收http请求,交给RequestHandler,解析出http请求的数据、然后调用ServerHandler,调用wsgi_handler,将数据传递Application(Django),写回数据

上面的整个请求流程如下

今天就分析到这里, 明天继续, 感兴趣的可以加群一起交流Dajngo的学习, QQ群: 279472055


本文分享自微信公众号 - 图解源码(sreguide)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部