### 执行时间和内容[](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类似。 响应头和响应体过滤函数的执行顺序如下所示: ![](https://box.kancloud.cn/2015-08-12_55cb06b1e5fbd.png) 这图只表示了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这个变量与一般的内容处理模块不同。