### 執行時間和內容[](http://tengine.taobao.org/book/chapter_04.html#id3 "永久鏈接至標題")
過濾(filter)模塊是過濾響應頭和內容的模塊,可以對回復的頭和內容進行處理。它的處理時間在獲取回復內容之后,向用戶發送響應之前。它的處理過程分為兩個階段,過濾HTTP回復的頭部和主體,在這兩個階段可以分別對頭部和主體進行修改。
在代碼中有類似的函數:
ngx_http_top_header_filter(r);
ngx_http_top_body_filter(r, in);
就是分別對頭部和主體進行過濾的函數。所有模塊的響應內容要返回給客戶端,都必須調用這兩個接口。
### 執行順序?[](http://tengine.taobao.org/book/chapter_04.html#id4 "永久鏈接至標題")
過濾模塊的調用是有順序的,它的順序在編譯的時候就決定了。控制編譯的腳本位于auto/modules中,當你編譯完Nginx以后,可以在objs目錄下面看到一個ngx_modules.c的文件。打開這個文件,有類似的代碼:
ngx_module_t *ngx_modules[] = {
...
&ngx_http_write_filter_module,
&ngx_http_header_filter_module,
&ngx_http_chunked_filter_module,
&ngx_http_range_header_filter_module,
&ngx_http_gzip_filter_module,
&ngx_http_postpone_filter_module,
&ngx_http_ssi_filter_module,
&ngx_http_charset_filter_module,
&ngx_http_userid_filter_module,
&ngx_http_headers_filter_module,
&ngx_http_copy_filter_module,
&ngx_http_range_body_filter_module,
&ngx_http_not_modified_filter_module,
NULL
};
從write_filter到not_modified_filter,模塊的執行順序是反向的。也就是說最早執行的是not_modified_filter,然后各個模塊依次執行。所有第三方的模塊只能加入到copy_filter和headers_filter模塊之間執行。
Nginx執行的時候是怎么按照次序依次來執行各個過濾模塊呢?它采用了一種很隱晦的方法,即通過局部的全局變量。比如,在每個filter模塊,很可能看到如下代碼:
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
...
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_example_header_filter;
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_example_body_filter;
ngx_http_top_header_filter是一個全局變量。當編譯進一個filter模塊的時候,就被賦值為當前filter模塊的處理函數。而ngx_http_next_header_filter是一個局部全局變量,它保存了編譯前上一個filter模塊的處理函數。所以整體看來,就像用全局變量組成的一條單向鏈表。
每個模塊想執行下一個過濾函數,只要調用一下ngx_http_next_header_filter這個局部變量。而整個過濾模塊鏈的入口,需要調用ngx_http_top_header_filter這個全局變量。ngx_http_top_body_filter的行為與header fitler類似。
響應頭和響應體過濾函數的執行順序如下所示:

這圖只表示了head_filter和body_filter之間的執行順序,在header_filter和body_filter處理函數之間,在body_filter處理函數之間,可能還有其他執行代碼。
### 模塊編譯?[](http://tengine.taobao.org/book/chapter_04.html#id5 "永久鏈接至標題")
Nginx可以方便的加入第三方的過濾模塊。在過濾模塊的目錄里,首先需要加入config文件,文件的內容如下:
ngx_addon_name=ngx_http_example_filter_module
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_example_filter_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_example_filter_module.c"
說明把這個名為ngx_http_example_filter_module的過濾模塊加入,ngx_http_example_filter_module.c是該模塊的源代碼。
注意HTTP_AUX_FILTER_MODULES這個變量與一般的內容處理模塊不同。
- 上篇:nginx模塊開發篇
- nginx平臺初探
- 初探nginx架構
- nginx基礎概念
- connection
- request
- keepalive
- pipe
- lingering_close
- 基本數據結構
- ngx_str_t
- ngx_pool_t
- ngx_array_t
- ngx_hash_t
- ngx_hash_wildcard_t
- ngx_hash_combined_t
- ngx_hash_keys_arrays_t
- ngx_chain_t
- ngx_buf_t
- ngx_list_t
- ngx_queue_t
- nginx的配置系統
- 指令參數
- 指令上下文
- nginx的模塊化體系結構
- 模塊的分類
- nginx的請求處理
- handler模塊
- handler模塊簡介
- 模塊的基本結構
- 模塊配置結構
- 模塊配置指令
- 模塊上下文結構
- 模塊的定義
- handler模塊的基本結構
- handler模塊的掛載
- handler的編寫步驟
- 示例: hello handler 模塊
- handler模塊的編譯和使用
- 更多handler模塊示例分析
- http access module
- http static module
- http log module
- 過濾模塊
- 過濾模塊簡介
- 過濾模塊的分析
- upstream模塊
- upstream模塊
- upstream模塊接口
- memcached模塊分析
- 本節回顧
- 負載均衡模塊
- 配置
- 指令
- 鉤子
- 初始化配置
- 初始化請求
- peer.get和peer.free回調函數
- 本節回顧
- 其他模塊
- core模塊
- event模塊
- 模塊開發高級篇
- 變量
- 下篇:nginx原理解析篇
- nginx架構詳解
- nginx的源碼目錄結構
- nginx的configure原理
- 模塊編譯順序
- nginx基礎設施
- 內存池
- nginx的啟動階段
- 概述
- 共有流程
- 配置解析
- nginx的請求處理階段
- 接收請求流程
- http請求格式簡介
- 請求頭讀取
- 解析請求行
- 解析請求頭
- 請求體讀取
- 讀取請求體
- 丟棄請求體
- 多階段處理請求
- 多階段執行鏈
- POST_READ階段
- SERVER_REWRITE階段
- FIND_CONFIG階段
- REWRITE階段
- POST_REWRITE階段
- PREACCESS階段
- ACCESS階段
- POST_ACCESS階段
- TRY_FILES階段
- CONTENT階段
- LOG階段
- Nginx filter
- header filter分析
- body filter分析
- ngx_http_copy_filter_module分析
- ngx_http_write_filter_module分析
- subrequest原理解析
- https請求處理解析
- 附錄A 編碼風格
- 附錄B 常用API
- 附錄C 模塊編譯,調試與測試