1. HTTPServer,RequestHandler,ServerHandler,Handler
1.1 基本概念
HTTPServer主要是對傳輸控制層HTTP,TCP,Socket等底層實現細節的一些抽象,典型應用為WSGIServer,其繼承關系為: WSGIServer: HTTPServer: TCPServer: SocketServer.BaseServer,對應的類視圖如下圖:
RequestHandler是對HTTP請求所有操作的抽象,從其成員函數:headers, response, parse_request(), handle_one_request()等即可大致了解其主要工作內容,其典型的應用是WSGIRequestHandler,對應的繼承關系為: WSGIRequestHandler: BaseHTTPRequestHander: StreamRequestHandler: SocketServer.BaseRequestHandler。對應的類視圖如下:
ServerHandler是對程序運行環境進行抽象,如stdin, stdout, softversion, logging等,主要起輔助作用,其具體工作機制暫時不得知,其有一個重要的成員函數run(self, application),HTTPServer利用該成員函數調用不同的Handler處理不同的請求。
Handler是對URL請求進行處理的一種抽象,重點偏向上層應用處理,不同的URL請求可能需要不同的處理機制,因此需要定制多種不同的Handler,Handler實體對應Server的application成員,顯然,雖然Server在初始化時賦值了該application成員(wsgi_handler),但是程序在運行過程中,隨時可以動態調整該成員值以達到調用不同的Handler處理不同Request的目的。Handler的典型應用有staticfileHandler, WSGIHandler。前者的類視圖如下圖:
Handler實體中loadmiddleware(), get_response(), _get_response(), make_view_atomic()都是非常重要的成員函數,完成對http請求處理的絕大部分操作。
Django程序通常擁有一個HTTPServer實體,一個HTTPServer實體與一個RequestHandler關聯,RequestHandler在handle請求時需要一個ServerHandler實體的支撐,一個ServerHandler實體調用HTTPServer實體對應的多個Handler中一個進行請求處理。
在Django框架中,WSGI協議是連接Django框架和外部web server的橋梁,起着非常核心的作用,因此在分析過程中通常直接分析WSGISserver,WSGIHandler,WSGIRequestHandler,而不再介紹更抽象的HTTPServer,Handler等,關於這些抽象類的更多應用可以在python目錄的test文件夾找到。
1.2 類視圖關系
WSGISserver,WSGIRequestHandler ,ServerHandler,WSGIHandler之間的關聯關系如下圖所示:
1.3 初始化及其調用關系
django.core.management.base.commands.runserver.py
from django.core.servers.basehttp import get_internal_wsgi_application, run
handler = self.get_handler(*args, **options) /* WSGIHandler 或StaticFilesHandler */
run(self.addr, int(self.port), handler, ipv6=self.use_ipv6, threading=threading)
django.core.servers.basehttp.py
def run(addr, port, wsgi_handler, ipv6=False, threading=False):
httpd = WSGIServer(server_address, WSGIRequestHandler, ipv6=ipv6) /*初始化WSGIServer實體,並指定RequestHandler為WSGIRequestHandler */
httpd.set_app(wsgi_handler) /*指定applicaton為wsgi_handler */
httpd.serve_forever() /*啟動服務,接受到來的請求,並處理之*/
注意,在RunserverCommand:Commond:get_handler()獲取Handler時,根據配置參數不同,返回不同的Handler,即WSGIHandler 或者StaticFilesHandler。
if use_static_handler and (settings.DEBUG or insecure_serving):
return StaticFilesHandler(handler)
return handler /* WSGIHandler*/