tornado學習筆記18 _RequestDispatcher 請求分發器

根據Application的配置,主要負責將客戶端的請求分發到具體的RequestHandler。這個類實現了HTTPMessageDelegate接口。正則表達式

18.1 構造函數

定義:緩存

def __init__(self, application, connection):

參數:app

application:Application對象。函數

connection:請求鏈接,爲HTTP1Connection實例。oop

實現分析:post

就是對這個類的屬性進行初始化賦值。好比chunks,handler_class(RequestHandler處理類)、handler_kwargs(處理類參數)、path_args、path_kwargs等。網站

18.2 HTTPMessageDelegate接口實現

1.2.1 header_received

定義ui

def headers_received(self, start_line, headers):

實現分析:spa

實例化HTTPServerRequest對象,調用set_request方法,set_request方法中去查找匹配的請求處理類(RequestHandler)。若是請求處理類實現了_stream_request_body方法,則直接調用execute方法。debug

1.2.2 data_received

定義

def data_received(self, data):

實現過程:

若是RequestHandler實現了_stream_request_body方法,則調用handler的data_received方法,若是沒實現,則將數據塊添加至chunks中。

1.2.3 finish

當消息數據塊接收完畢後,調用此方法。此方法的實現就是將數據塊鏈接起來,而後調用HTTPServerReuqest的_parse_body方法,實現對body體消息的解析。而後調用excute方法。

18.3 其餘方法

1.3.1 _find_handler

這個方法很重要,也是核心方法之一。實現Application的配置屬性以及請求路徑的匹配,找到匹配的RequestHandler。

實現過程:

(1) 調用Application的_get_host_handlers方法,得到匹配的hanlders集合;

(2) 若是沒有匹配到合適的handlers,將handler_class設置成RedirectHandler,並設置handler_kwargs,而後返回。

(3) 若是匹配到了合適的handlers,循環handlers中的每一元素URLSpec,判斷其中的路徑正則表達式是否與請求路徑相匹配。

(4) 若是匹配合適的RequestHandler,設置handler_class以及handler_kwargs,然後設置path_kwargs

(5) 沒有沒有匹配到RequestHandler,判斷Application是否設置了default_handler_class選項,並設置handler_class爲其值。若是沒有設置default_handler_class選項,則將handler_class屬性設置成 ErrorHandler,狀態碼設置成404錯誤,也就是not found錯誤。

18.3.2 execute

這個方法很核心,也很重要。當請求信息處理完畢後(調用finish方法後),會執行execute方法。方法以下:

def execute(self):    # If template cache is disabled (usually in the debug mode),
    # re-compile templates and reload static files on every
    # request so you don't need to restart to see changes
    if not self.application.settings.get("compiled_template_cache", True):
        with RequestHandler._template_loader_lock:
            for loader in RequestHandler._template_loaders.values():
                loader.reset()
    if not self.application.settings.get('static_hash_cache', True):
        StaticFileHandler.reset()

    self.handler = self.handler_class(self.application, self.request,
                                      **self.handler_kwargs)
    transforms = [t(self.request) for t in self.application.transforms]

    if self.stream_request_body:
        self.handler._prepared_future = Future()
    # Note that if an exception escapes handler._execute it will be
    # trapped in the Future it returns (which we are ignoring here,
    # leaving it to be logged when the Future is GC'd).
    # However, that shouldn't happen because _execute has a blanket
    # except handler, and we cannot easily access the IOLoop here to
    # call add_future (because of the requirement to remain compatible
    # with WSGI)
    f = self.handler._execute(transforms, *self.path_args,
                              **self.path_kwargs)
    # If we are streaming the request body, then execute() is finished
    # when the handler has prepared to receive the body.  If not,
    # it doesn't matter when execute() finishes (so we return None)
    return self.handler._prepared_future

實現過程描述以下:

(1) 判斷application是否對complied_template_cache是否設置成True.若是沒有,則將模板加載器重置。至關於不對編譯後模板緩存的話,就重置模板加載器。

(2) 判斷applacation是否對static_hash_cache是否設置成True. 若是沒有,則調用StaticFileHandler的reset方法。至關於不對網站的靜態文件進行緩存的話,就調用重置的方法。

(3) 根據_find_handler方法設置的handler_class屬性初始化自定義的RequestHanlder

(4) 調用requestHandler的_exucute方法,就是調用相應的方法,要門是get方法,要麼是post,要麼是其餘支持的http方法,具體實現詳情請查看RequestHandler類。

相關文章
相關標籤/搜索