Filter在在回调函数post-configuration中被装载。header filter和body filter都是在这里被装载的。
我们以chunked filter模块为例来具体看看:
static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
NULL, /* preconfiguration */
ngx_http_chunked_filter_init, /* postconfiguration */
...
};
ngx_http_chunked_filter_init中的具体实现如下:
static ngx_int_t
ngx_http_chunked_filter_init(ngx_conf_t *cf)
{
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_chunked_header_filter;
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_chunked_body_filter;
return NGX_OK;
}
发生了什么呢?好吧,如果你还记得,过滤模块组成了一条”接力链表“。当handler生成一个响应后,调用2个函数:ngx_http_output_filter它调用全局函数ngx_http_top_body_filter;以及 ngx_http_send_header 它调用全局函数ngx_top_header_filter。
ngx_http_top_body_filter 和 ngx_http_top_header_filter是body和header各自的头部filter链的”链表头“。链表上的每一个”连接“都保存着链表中下一个连接的函数引用(分别是 ngx_http_next_body_filter 和 ngx_http_next_header_filter)。当一个filter完成工作之后,它只需要调用下一个filter,直到一个特殊的被定义成”写“的filter被调用,这个”写“filter的作用是包装最终的HTTP响应。你在这个filter_init函数中看到的就是,模块把自己添加到filter链表中;它先把旧的”头部“filter当做是自己的”下一个“,然后再声明”它自己“是”头部“filter。(因此,最后一个被添加的filter会第一个被执行。)
边注: 这到底是怎么工作的?
每个filter要么返回一个错误码,要么用`return ngx_http_next_body_filter();`来作为返回语句
因此,如果filter顺利链执行到了链尾(那个特别定义的的”写“filter),将返回一个"OK"响应,但如果执行过程中遇到了错误,链将被砍断,同时Nginx将给出一个错误的信息。这是一个单向的,错误快速返回的,只使用函数引用实现的链表。帅啊!
4 天 2 小时之前
5 天 7 小时之前
1 周 2 天之前
1 周 5 天之前
1 周 5 天之前
1 周 6 天之前
2 周 7 小时之前
2 周 3 天之前
3 周 4 天之前
4 周 3 天之前