Flask 源码解析:请求和响应
Falsk 示例
1 |
|
werkzeug 源码 讲到,执行 app.run()
最后执行的是 run_simple()
,run_simple()
做了两件事
- 一件
make_server
,创建服务器 - 一件
server_forver
,一直在监听端口
run_simple
三个参数
- environ 为初步处理的 request 请求
- start_response 为回调函数
- Response 的实例化对象,也是具体的 request 入口,负责具体的逻辑,不同的框架其实是第三个参数不同。
当有请求过来之后,server_forever
会将 run_simple()
中的第三个参数加括号执行,并传入参数 (environ, start_response)
。
请求和响应整体流程
当请求到来,执行 __call__
方法。看一下源码。
1 |
|
下面来看下 Response 对象,HTTP 格式的返回就是三部分 status,headers, body
1 |
|
可以看出,最终的 response 转换为 二进制形式。下面再来看下 Headers 类。
1 |
|
流程
- 当一个 HTTP 请求来临时,WSGI server 将 HTTP 格式数据转换为 WSGI 格式数据,并调用
Flask.__call__(environ, start_response)
。__call__
方法调用调用wsgi_app
方法,具体流程如下:- 使用 environ 来构建
flask.Request
对象,这样后续view_function
中我们可以通过flask.request
从中获取需要的请求信息 - 根据 environ 路由到具体的
view_function
执行,并返回 - 将
view_function
的返回转换为flask.Response
对象,并最终以 WSGI 的方式将 status、headers、response body 返回给 WSGI Server
- 使用 environ 来构建
- 最后,WSGI Server 再将 WSGI 格式的数据转换为 HTTP 格式的数据返回给客户端
可见:WSGI Server 主要进行请求数据的格式转换:HTTP <–> WSGI。然后 Flask 作为 WSGI app 以 WSGI 的方式被调用、执行、返回。
session 流程
源码 wsgi_app
中,request_context
把我们的 environ 封装到了一个类 RequestContext。我们看下类 RequestContext 源码
1 |
|
回到 wsgi_app
中的 ctx 实例,ctx 会得到:
ctx.request=Request(environ)
。environ 是一个原始的请求对象。我们就可以执行.args
、.form
、.method"
等。ctx.session=None
ctx.app=app
看 session_interface
源码
1 |
|
push
其实调用的是 open_session
,pop
其实调用的是 save_session
,看 open_session
和 save_session
源码
1 |
|
open_session
返回啥 self.session
中就是啥。ctx.push()
中关于 session 的流程:执行 SecureCookieSessionInterface.open_session()
,去 cookie 中获取值,并反序列化解密之后给 ctx.session
重新赋值。
这就是 Flask 框架中 sesion 的请求流程。说了这么多,其实真正实现咱们想要的功能的就是两个方法:open_session
、save_session
。请求进来执行open_session
,请求走的时候执行 save_session
。
加了 session 的流程
- 当一个 HTTP 请求来临时,WSGI server 将 HTTP 格式数据转换为 WSGI 格式数据,并调用
Flask.__call__(environ, start_response)
。__call__
方法调用wsgi_app
方法,具体流程如下:- 将 request 和 session 相关封装到
ctx = RequestContext
对象中,此时 session 为空,request 二次封装 - 将 app 和 g 封装到
app_ctx = AppContext
对象中。 - 再通过 LocalStack 对象将 ctx、app_ctx 封装到 Local 对象中。
- 根据 environ 路由到具体的
view_function
执行,并返回 - 将
view_function
的返回转换为flask.Response
对象,并最终以 WSGI 的方式将 status、headers、response body 返回给 WSGI Server
- 将 request 和 session 相关封装到
- 最后,WSGI Server 再将 WSGI 格式的数据转换为 HTTP 格式的数据返回给客户端
- 获取数据:通过 LocalProxy 对象+偏函数,调用 LocalStack 去 Local 中获取相应 ctx、app_ctx 中封装的值。
- 请求结束:调用 LocalStack 的 pop 方法,将 ctx 和 app_ctx 移除。