#这里会执行Flask.__call__()方法
app.run(debug=True, use_reloader=True)
#这里执行__call__方法
def __call__(self, environ, start_response):
"""Shortcut for :attr:`wsgi_app`."""
return self.wsgi_app(environ, start_response)
#返回的wsgi_app
def wsgi_app(self, environ, start_response):
#这里返回一个上下文对象
ctx = self.request_context(environ)
#将上下文对象放入{'ident':{'stack':[]}}的列表中,具体分析见http://blog.csdn.net/qq_33733970/article/details/78984955
ctx.push()
#让我们看下self.request_context中具体做了什么?
def request_context(self, environ):
return RequestContext(self, environ)
#我们看下这个RequestContext中都有什么?
class RequestContext(object):
def __init__(self, app, environ, request=None):
self.app = app
#首先处理了request,
if request is None:
###request_class = Request
request = app.request_class(environ)
self.request = request
self.url_adapter = app.create_url_adapter(self.request)
self.flashes = None
#定义了一下session,这时的session为None
self.session = None
#现在我们看下ctx.push()中做了什么
def push(self):
#处理session核心代码
self.session = self.app.open_session(self.request)
if self.session is None:
#如果session为None:返回NullSession
self.session = self.app.make_null_session()
#看下它是怎么处理session的:
#我们看下self.session = self.app.open_session(self.request)是什么?
#调用了app的open_session:
def open_session(self, request):
#SecureCookieSessionInterface().open_session()
return self.session_interface.open_session(self, request)
#看下session_interface是什么鬼?
session_interface = SecureCookieSessionInterface()
#接着看下open_session内部做了什么?
def open_session(self, app, request):
#获取加解密对象
s = self.get_signing_serializer(app)
if s is None:
return None
# 从cookies中获取cookie的名字:'session'
val = request.cookies.get(app.session_cookie_name)
if not val:
#如果val为空,则返回SecureCookieSession对象,相当于{}
#session_class = SecureCookieSession
return self.session_class()
max_age = total_seconds(app.permanent_session_lifetime)
try:
# 解密返回原始数据
data = s.loads(val, max_age=max_age)
#session_class = SecureCookieSession相当于{},根据代码追溯可以发现,基类继承dict
#"""Base class for sessions based on signed cookies."""
#翻译一下:基于加密cookies的session基类
return self.session_class(data)
except BadSignature:
return self.session_class()
#这里session已经处理完毕,接着我们回去看
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
ctx.push()
error = None
try:
try:
# 处理视图函数
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)
#看下这个代码内部实现:response = self.full_dispatch_request()
def full_dispatch_request(self):
#首先执行before_first_request函数
self.try_trigger_before_first_request_functions()
try:
request_started.send(self)
#预处理请求,在真正的请求处理之前调用,如果有返回值不会进一步请求,看代码执行也是这样的。
rv = self.preprocess_request()
if rv is None:
#处理请求分发,匹配url,返回视图函数的返回值,或者异常,这里没有必要是一个response对象,如果想要转化为一个对象,调用make_response
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
#最后这个方法的意思,视图函数的返回值当做参数传入,返回一个response并触发后续处理函数,完成request请求。
return self.finalize_request(rv)
#到此request处理分析完毕,那么ctx.auto_pop(error)就不分析了,上篇文章有介绍,详见:http://blog.csdn.net/qq_33733970/article/details/78984955
flask之源码解读session处理流程
最新推荐文章于 2022-04-12 15:59:12 发布