HTTP請求的11個處理階段
typedef enum {
// 接收到完整的HTTP頭部後處理階段
NGX_HTTP_POST_READ_PHASE = 0,
// 將請求URI與location表達式匹配前,修改URI,即重定向階段
NGX_HTTP_SERVER_REWRITE_PHASE,
// 只能由ngx_http_core_module模塊實現,用於根據請求URI尋找location表達式
NGX_HTTP_FIND_CONFIG_PHASE,
// 上一過程結束後修改URI
NGX_HTTP_REWRITE_PHASE,
// 爲了防止rewrite造成死循環(一個請求執行10次會被Nginx認定爲死循環)
NGX_HTTP_POST_REWRITE_PHASE,
// 在“決定請求訪問權限”階段前
NGX_HTTP_PREACCESS_PHASE,
// 決定訪問權階段,判斷該請求是否可以訪問Nginx服務器
NGX_HTTP_ACCESS_PHASE,
// 當然請求不被允許訪問Nginx服務器時,該階段負責向用戶返回錯誤響應
NGX_HTTP_POST_ACCESS_PHASE,
// 用try_files配置項。順序訪問多個靜態文件資源階段
NGX_HTTP_TRY_FILES_PHASE,
// 處理HTTP請求內容階段,這是大部分HTTP模塊介入的階段
NGX_HTTP_CONTENT_PHASE,
// 記錄日誌階段
NGX_HTTP_LOG_PHASE
} ngx_http_phases;
處理階段的數據結構
typedef struct ngx_http_phase_handler_s ngx_http_phase_handler_t;
// 一個HTTP階段的checker檢查方法,僅有HTTP框架實現
typedef ngx_int_t (*ngx_http_phase_handler_pt)(ngx_http_request_t *r,
ngx_http_phase_handler_t *ph);
// 由HTTP模塊實現的handler處理方法
typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r);
struct ngx_http_phase_handler_s {
// 在處理一個HTTP階段時,最先調用這個checker檢查方法,在checker方法中調用模塊實現的handler方法
ngx_http_phase_handler_pt checker;
// 用於定義HTTP模塊處理方法
ngx_http_handler_pt handler;
// 將要執行的下一個HTTP處理階段序號,可以不按順序執行(這些處理階段結構體都被存放在一個數組中,所以可以有下標序號
ngx_uint_t next;
};
在一個http{}塊解析完後,會根據nginx.conf中的配置項產生由ngx_http_phase_handler_t(上述結構)組成的數組。在處理HTTP請求時,按照next的順序執行。這個組成的數組,被作爲另一個結構體:
ngx_http_phase_engine_t
typedef struct {
// 由ngx_http_phase_handler_t構成的數組首地址,表示一個請求可能經歷的所有ngx_http_handler_pt處理方法
ngx_http_phase_handler_t *handlers;
// 表示NGX_HTTP_SERVER_REWRITE_PHASE階段第一個ngx_http_phase_handler_t處理方法在handlers數組中的序號
ngx_uint_t server_rewrite_index;
// 表示NGX_HTTP_REWRITE_PHASE階段第一個ngx_http_phase_handler_t處理方法在handlers數組中的序號
ngx_uint_t location_rewrite_index;
} ngx_http_phase_engine_t;
這個數組被保存在了ngx_http_core_main_conf_t結構中:
typedef struct {
ngx_http_phase_engine_t phase_engine;
...
// 在HTTP框架初始化時幫助各個HTTP模塊在任意階段中添加HTTP處理方法,它是一個有11個ngx_http_phase_t成員的數組,在初始化完畢後是沒用的
ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1];
...
} ngx_http_core_main_conf_t;
ngx_http_phase_t
typedef struct {
// handlers動態數組保存着每一個HTTP模塊初始化時添加到當前階段處理方法
ngx_array_t handlers;
} ngx_http_phase_t;