zoukankan      html  css  js  c++  java
  • flask--session源码解析

     

    一:session源码开始

    1,创建起始连接

    from flask import Flask
    from index import app
    
    app=Flask(__name__)
    
    
    if __name__ == '__main__':
        app.__call__
        app.run()

    2,开始请求app.__call__

        def __call__(self, environ, start_response):
            """Shortcut for :attr:`wsgi_app`."""
            return self.wsgi_app(environ, start_response)

    3,执行wsgi_app方法

    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)
    def wsgi_app(self, environ, start_response):

    ==> ctx = self.request_context(environ)
    def request_context(self, environ):
        return RequestContext(self, environ)
    
    class RequestContext(object):
        def __init__(self, app, environ, request=None):
               self.app = app
               if request is None:
                request = app.request_class(environ)
               self.request = request
    生成RequestContext()对象 封装请求相关的数据(request,session)
    ==>  ctx.push()
    def push(self):
        self.session = self.app.open_session(self.request) #开始运行session
            if self.session is None:        #如果没有session
                self.session = self.app.make_null_session()
    ==> def open_session(self, app, request)
    开始执行session
        def open_session(self, app, request):
            sid = request.cookies.get(app.session_cookie_name)  #如果能从cookie拿到session的话
            if not sid:
                sid = self._generate_sid()
                return self.session_class(sid=sid, permanent=self.permanent)    #如果没有session,则返回一个空字典
            if self.use_signer:
                signer = self._get_signer(app)
                if signer is None:
                    return None
                try:
                    sid_as_bytes = signer.unsign(sid)
                    sid = sid_as_bytes.decode()
                except BadSignature:
                    sid = self._generate_sid()
                    return self.session_class(sid=sid, permanent=self.permanent)
    
            if not PY2 and not isinstance(sid, text_type):
                sid = sid.decode('utf-8', 'strict')
            val = self.redis.get(self.key_prefix + sid)
            if val is not None:
                try:
                    data = self.serializer.loads(val)    #加密val
                    return self.session_class(data, sid=sid) 
                except:
                    return self.session_class(sid=sid, permanent=self.permanent)
            return self.session_class(sid=sid, permanent=self.permanent)  #把session加到字典里
    View Code
    ==>  def full_dispatch_request(self):
    当视图函数执行完成,要把session保存到session里面
    self.try_trigger_before_first_request_functions()
            try:
                #视图函数开始,发送信号
                print(self)
                request_started.send(self)
                rv = self.preprocess_request()
                if rv is None:
                    rv = self.dispatch_request()
            except Exception as e:
                rv = self.handle_user_exception(e)
            return self.finalize_request(rv)
    View Code
    ==> def finalize_request(self, rv, from_error_handler=False):
    上面是视图函数全部执行完成,开始保存数据,以及session,在process_responce里面存有所有数据
    response = self.make_response(rv)
            try:
                response = self.process_response(response)
                request_finished.send(self, response=response)
            except Exception:
                if not from_error_handler:
                    raise
                self.logger.exception('Request finalizing failed with an '
                                      'error while handling an error')
            return response
    View Code
    ==> def process_response(self, response):
    这里处理保存session,调用
    save_session
    ctx = _request_ctx_stack.top
            bp = ctx.request.blueprint
            funcs = ctx._after_request_functions
            if bp is not None and bp in self.after_request_funcs:
                funcs = chain(funcs, reversed(self.after_request_funcs[bp]))
            if None in self.after_request_funcs:
                funcs = chain(funcs, reversed(self.after_request_funcs[None]))
            for handler in funcs:
                response = handler(response)
            if not self.session_interface.is_null_session(ctx.session):
                self.save_session(ctx.session, response)
            return response
    View Code
    ==> def save_session(self, app, session, response):
    def save_session(self, app, session, response):
        domain = self.get_cookie_domain(app)   #域名
            path = self.get_cookie_path(app)    #路径
                if not session:
                if session.modified:
                    response.delete_cookie(app.session_cookie_name,
                                           domain=domain, path=path)
                return
                if not self.should_set_cookie(app, session):
                return
    
            httponly = self.get_cookie_httponly(app)
            secure = self.get_cookie_secure(app)
            expires = self.get_expiration_time(app, session)
            val = self.get_signing_serializer(app).dumps(dict(session))  加密
            response.set_cookie(app.session_cookie_name, val,           #最后保存到cookie里面
                                expires=expires, httponly=httponly,
                                domain=domain, path=path, secure=secure)




  • 相关阅读:
    接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架
    Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本
    Python 基于Python实现批量创建目录
    Loadrunner 脚本录制-通过代理录制脚本
    Clumsy 利用无线网卡结合Clumsy软件模拟弱网络测试
    Loadrunner 脚本开发-soap_request函数介绍及WebService接口测试
    Loadrunner脚本优化-参数化之关联MySQL数据库获取数据
    Postman Postman测试接口之POST提交本地文件数据
    Loadrunner 脚本开发-利用web_custom_request函数进行接口测试
    loadrunner 脚本开发-web_custom_request函数详细介绍
  • 原文地址:https://www.cnblogs.com/52forjie/p/8260120.html
Copyright © 2011-2022 走看看