flask源码解读02: app.run()的背后(续)

前面说到通过新建Handler类来处理请求

默认情况下Handler类为WSGIRequestHandler

class WSGIRequestHandler(BaseHTTPRequestHandler):

    server_version = "WSGIServer/" + __version__

    def get_environ(self):
        env = self.server.base_environ.copy()
        env['SERVER_PROTOCOL'] = self.request_version
        env['REQUEST_METHOD'] = self.command
        if '?' in self.path:
            path,query = self.path.split('?',1)
        else:
            path,query = self.path,''

        env['PATH_INFO'] = urllib.unquote(path)
        env['QUERY_STRING'] = query

        host = self.address_string()
        if host != self.client_address[0]:
            env['REMOTE_HOST'] = host
        env['REMOTE_ADDR'] = self.client_address[0]

        if self.headers.typeheader is None:
            env['CONTENT_TYPE'] = self.headers.type
        else:
            env['CONTENT_TYPE'] = self.headers.typeheader

        length = self.headers.getheader('content-length')
        if length:
            env['CONTENT_LENGTH'] = length

        for h in self.headers.headers:
            k,v = h.split(':',1)
            k=k.replace('-','_').upper(); v=v.strip()
            if k in env:
                continue                    # skip content length, type,etc.
            if 'HTTP_'+k in env:
                env['HTTP_'+k] += ','+v     # comma-separate multiple headers
            else:
                env['HTTP_'+k] = v
        return env

    def get_stderr(self):
        return sys.stderr

    def handle(self):
        """Handle a single HTTP request"""

        self.raw_requestline = self.rfile.readline()
        if not self.parse_request(): # An error code has been sent, just exit
            return

        handler = ServerHandler(
            self.rfile, self.wfile, self.get_stderr(), self.get_environ()
        )
        handler.request_handler = self      # backpointer for logging
        handler.run(self.server.get_app())

 

WSGIRequestHandler继承自BaseHTTPServer模块的BaseHTTPRequestHandler

BaseHTTPRequestHandler继承自SocketServer模块的StreamRequestHandler  

StreamRequestHandler继承自同一模块的BaseRequestHandler

class BaseRequestHandler:

    def __init__(self, request, client_address, server):
        self.request = request
        self.client_address = client_address
        self.server = server
        self.setup()
        try:
            self.handle()
        finally:
            self.finish()

    def setup(self):
        pass

    def handle(self):
        pass

    def finish(self):
        pass

在BaseRequestHandler的__init__方法中, 发现新建Handler对象时, 会调用self.handler处理请求, 处理完后调用self.finish。

沿着继承链发现WSGIRequestHandler和BaseHTTPRequestHandler都定义了hanlder方法, WSGIRequestHandler中的定义优先

 

class WSGIRequestHandler(BaseHTTPRequestHandler):

    server_version = "WSGIServer/" + __version__

    def handle(self):
        """Handle a single HTTP request"""

        self.raw_requestline = self.rfile.readline()
        if not self.parse_request(): # An error code has been sent, just exit
            return

        handler = ServerHandler(
            self.rfile, self.wfile, self.get_stderr(), self.get_environ()
        )
        handler.request_handler = self      # backpointer for logging
        handler.run(self.server.get_app())

在handler方法中, 新建了ServerHandler类实例, 再调用实例的run方法

再次建立ServerHandler类实例的原因是为了符合WSGI接口. 前面运行的程序的作用是建立了服务器, 服务器在指定端口监听, 接收来自客户端的连接, 读取客户端的请求. 现在开始处理客户端的请求, 但是处理的方式有很多种, 你也可以自己写一个程序解析客户端的请求, 生成响应并返回给客户端. 

但是符合WSGI接口的处理方式是: 底层程序解析好客户端的请求并生成environ字典, 这个字典表示客户端请求的各种信息. 另外定义start_response函数, 该函数用于向客户端发送响应起始行和响应头. 底层程序将environ, start_response传给编写好的app, app运行生成响应. 这就是符合WSGI接口的响应方式, 下面的程序可以清楚的显示.

    def run(self, application):
        """Invoke the application"""
        # Note to self: don't move the close()!  Asynchronous servers shouldn't
        # call close() from finish_response(), so if you close() anywhere but
        # the double-error branch here, you'll break asynchronous servers by
        # prematurely closing.  Async servers must return from 'run()' without
        # closing if there might still be output to iterate over.
        try:
            self.setup_environ()
            self.result = application(self.environ, self.start_response)
            self.finish_response()
        except:
            try:
                self.handle_error()
            except:
                # If we get an error handling an error, just give up already!
                self.close()
                raise

在handler的run方法中, 首先调用setup_environ创建了self.environ。

紧接着的语句: self.result = application(self.environ, self.start_response)说明定义的app必须是一个可调用对象,调用app的时候传入了self.environ, self.start_response两个参数。调用app返回的结果存放在self.result中,在finish_response调用中,将self.result返回给用户,至此用户的请求响应完毕

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/lovelaker007/p/8559146.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值