nginx过滤模块怎么生效的

在nginx中,如果你要开发一个过滤模块,config中必须要加

HTTP_FILTER_MODULES=$HTTP_FILTER_MODULES xxx

否则,即使在postconfiguration回调中加了ngx_http_top_header_filter=my_xxxx_filter_handle,最终my_xxxx_filter_handle也不会调用。这是如何做到的呢?

搜索HTTP_FILTER_MODULES,这个变量似乎没做什么事,就是保存了过滤模块而已。

我们知道只要加了HTTP_MODULES=$HTTP_MODULES xxx即可,我们的模块就生效了,而且postconfiguration也会被调用,在回调中设置了回调的链表。最终未被调用,其秘密就藏在了auto/modules这个脚本中

在其中搜索HTTP_FILTER_MODULES,可以看到:

这上面有段注释,说明了,过滤模块的顺序很重要,再往上则是说http模块顺序也很重要。

因此在HTTP_FILTER_MODULES下面有个ngx_module_order对模块进行了排序,这个决定了模块最终在全局变量ngx_modules数组中顺序位置。但是这里有个疑惑,这只是决定了模块在数组中的位置而已,他是如何决定config中加了HTTP_FILTER_MODULES变量后,过滤回调才能被调用的呢?

即,加了HTTP_FILTER_MODULES,你的过滤回调才能被调用,否则不可能。

以header_filter为例,

首先这个顺序是最重要,但是他是如何做到的呢?

答案就在ngx_http_header_filter_module这个模块中,

ngx_http_header_filter_module,是第一个被初始化的过滤模块

我们看其初始化函数:

static ngx_int_t

ngx_http_header_filter_init(ngx_conf_t *cf)

{

ngx_http_top_header_filter = ngx_http_header_filter;

return NGX_OK;

}

在这里,最先初始化ngx_http_top_header_filter,之后的模块则都是

xxx_next_header_filter=ngx_http_top_header_filter;

ngx_http_top_header_filter=xxx_header_filter;

依次来形成了回调链表。

如果我们的模块不是HTTP_FILTER_MODULES,那么我们的模块则一定排在ngx_http_header_filter_module之前,因此我们的模块被先初始化,即使我们挂了回调,那么等到调用ngx_http_header_filter_module模块初始化的时,直接重置了ngx_http_top_header_filter,使先前的链表直接失效了。这个排序在configiure执行后,可以在objs/ngx_modules.c可以看到。

nginx这样的设计是比较巧妙,如果你不显示告诉configure你是HTTP_FILTER_MODULES,那么最终程序中你的过滤回调就不会生效。

相关推荐
weixin_399380692 小时前
k8s一键部署tongweb企业版7049m6(by why+lqw)
java·linux·运维·服务器·云原生·容器·kubernetes
阿巴~阿巴~2 小时前
Linux基本命令篇 —— uname命令
linux·运维·服务器
IT成长日记2 小时前
【Docker基础】Docker数据卷管理:docker volume ls及其参数详解
运维·docker·容器·volume ls
zkmall4 小时前
企业电商解决方案哪家好?ZKmall模块商城全渠道支持 + 定制化服务更省心
大数据·运维·重构·架构·开源
绝不偷吃6 小时前
ELK日志分析系统
运维·elk·jenkins
朱包林6 小时前
day45-nginx复杂跳转与https
linux·运维·服务器·网络·云计算
孙克旭_6 小时前
day045-nginx跳转功能补充与https
linux·运维·nginx·https
Hacker_Oldv8 小时前
软件测试(功能、工具、接口、性能、自动化、测开)详解
运维·自动化
Java樱木8 小时前
使用字节Trae + MCP,UI 到网页自动化。
运维·自动化
无敌暴龙兽z11 小时前
离线环境安装elk及设置密码认证
运维·elk