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

相关推荐
默|笙4 小时前
【Linux】进程(6)虚拟地址空间
linux·运维·服务器
linzihahaha4 小时前
vmware-ubuntu 虚拟机共享文件及复制拖动配置
linux·运维·ubuntu
重生之我在番茄自学网安拯救世界4 小时前
网络安全中级阶段学习笔记(十一):服务器解析漏洞全解析(原理、利用与防御)
运维·服务器·web安全·网络安全·渗透测试·服务器解析漏洞
HIT_Weston5 小时前
70、【Ubuntu】【Hugo】搭建私人博客:新建站点
linux·运维·ubuntu
麦麦Max5 小时前
Docker
运维·docker·容器
Danileaf_Guo5 小时前
让Ubuntu服务器变身OSPF路由器!实现服务器与网络设备直接对话
linux·运维·服务器·ubuntu
HalvmånEver5 小时前
Linux:库制作与原理(三)
linux·运维·服务器
chinesegf5 小时前
gunicorn 进程管理的常用命令
linux·运维·gunicorn
木子欢儿5 小时前
在 Debian 13 上搭建一个 NTP (Network Time Protocol) 服务器
运维·服务器·开发语言·debian·php