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,那么最终程序中你的过滤回调就不会生效。

相关推荐
bearpping6 小时前
Nginx 配置:alias 和 root 的区别
前端·javascript·nginx
maosheng11466 小时前
RHCSA的第一次作业
linux·运维·服务器
旺仔.2917 小时前
Linux 信号详解
linux·运维·网络
Hoshino.417 小时前
基于Linux中的数据库操作——下载与安装(1)
linux·运维·数据库
恒创科技HK8 小时前
通用型云服务器与计算型云服务器:您真正需要哪些配置?
运维·服务器
吴佳浩 Alben9 小时前
GPU 生产环境实践:硬件拓扑、显存管理与完整运维体系
运维·人工智能·pytorch·语言模型·transformer·vllm
播播资源9 小时前
CentOS系统 + 宝塔面板 部署 OpenClaw源码开发版完整教程
linux·运维·centos
学不完的10 小时前
Docker数据卷管理及优化
运维·docker·容器·eureka
lay_liu10 小时前
Linux安装redis
linux·运维·redis
曾经拒绝刘亦菲12 小时前
Clamav在麒麟V10离线安装指南
运维