博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

TCPSever建立socket连接后,将socket包装成IOStream类,然后调用self.handle_stream()函数处理

tornado.httpserver.HTTPServer 继承了TCPSever,实现了handle_stream()方法。

 

HTTPSever通过两个类来实现从socket中读取http请求消息:tornado.http1connection.HTTP1ServerConnection与tornado.http1connection.HTTP1Connection

HTTP1ServerConnection,实现一个死循环,用于驱动HTTP1Connection。

HTTP1Connection从socket中读取数据,按照http消息的格式进行解析,生成对应保存header、body信息的python类,之后调用HTTPSever给它的处理对象进行处理。

具体过程如下

class HTTPServer(TCPServer,Configurable,httputil.HTTPServerConnectionDelegate):   
    def __init__(self, application):
        #http服务器处理http消息的部分,在下一节分析
        self.delegate = _CallableAdapter(application)
     
    def handle_stream(self, stream, address):
        context = _HTTPRequestContext(stream, address,
                                          self.protocol,
                                          self.trusted_downstream)
            
        #将连接包装成一个HTTP1ServerConnection对象,该对象提供了从socket中读取并解析http消息的函数start_serving
        conn = HTTP1ServerConnection(stream, self.conn_params, context) 
            
        self._connections.add(conn)
            
        #开始从socket中读取数据,并且传入用于处理解析出来的header、body的类
        conn.start_serving(self.delegate)

class HTTP1ServerConnection(object):
    def start_serving(self, delegate):
        self._serving_future = self._server_request_loop(delegate)
    
    @gen.coroutine
    def _server_request_loop(self, delegate):
        #死循环,不断的从socket中读取数据,每次循环会读取一个完整的http消息
        while True:
            conn = HTTP1Connection(self.stream, False,
                                   self.params, self.context)
            request_delegate = delegate.start_request(self, conn)
            ret = yield conn.read_response(request_delegate)

class HTTP1Connection(httputil.HTTPConnection):
    def read_response(self, delegate):
        if self.params.decompress:
            delegate = _GzipMessageDelegate(delegate, self.params.chunk_size)
        return self._read_message(delegate)

    @gen.coroutine
    def _read_message(self, delegate):
        #异步读取http消息头部
        header_future = self.stream.read_until_regex(
            b"\r?\n\r?\n",
            max_bytes=self.params.max_header_size)
        header_data = yield header_future
        
        #解析http消息头部
        start_line, headers = self._parse_headers(header_data)
        
        #调用上层即HTTPServer处理解析出来的http消息头部,该处理也是异步的
        header_future = delegate.headers_received(start_line, headers)
        if header_future is not None:
            yield header_future
        
        ...... #会根据头部的数据判断是否有body存在   具体过程略
        
        #如果有body部分则继续读取body部分并处理,同样也是异步的读,然后调用上层HTTPServer处理,具体过程略
        if not skip_body:
            body_future = self._read_body(start_line.code if self.is_client else 0, headers, delegate)
            yield body_future