nginx过滤post请求头_Nginx开发一个简单的HTTP过滤模块

本文将学些开发一个简单的HTTP过滤模块,它能够对Content-Type为text/plain的包体前加上前缀字符串prefix.

过滤模块的调用顺序

过滤模块可以叠加,也就是说一个请求会被所有的HTTP过滤模块依次处理。

过滤模块的调用时有顺序的,它的顺序在编译的时候就决定了。控制编译的脚本位于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源码时,已经定义了一个由所有HTTP过滤模块组成的单链表,这个单链表是这样的:链表的每个元素都是一个C源代码文件,这个C源代码文件中有两个指针,分别指向下一个过滤模块(文件)的过滤头部和包体的方法(可理解为链表中的next指针)

过滤模块单链表示意图:

这两个指针的声明如下:/*过滤模块处理HTTP头部的函数指针类型定义,它携带一个参数:请求*/

typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);

/*过滤模块处理HTTP包体的函数指针类型定义,它携带两个参数:请求、要发送的包体*/

typedef ngx_int_t (*ngx_http_output_body_filter_pt) (ngx_http_request_t *r, ngx_chain_t *chain);

在我们定义的第三方模块中则有如下声明:static ngx_http_output_header_filter_pt ngx_http_next_header_filter;

static ngx_http_output_body_filter_pt ngx_http_next_body_filter;

那么怎么将这个源文件(节点),插入到HTTP过滤模块组成的单链表中去呢?Nginx采用头插法的办法,所有的新节点都插入在链表的开头://插入到头部处理方法链表的首部

ngx_http_next_header_filter=ngx_http_top_header_filter;

ngx_http_top_header_filter=ngx_http_myfilter_header_filter;

//插入到包体处理方法链表的首部

ngx_http_next_body_filter=ngx_http_top_body_filter;

ngx_http_top_body_filter=ngx_http_myfilter_body_filter;

其中,两个top指针声明如下:

extern ngx_http_output_header_filter_pt ngx_http_next_header_filter;

extern ngx_http_output_body_filter_pt ngx_http_next_body_filter;

由于是头插法,这样就解释了,越早插入链表的过滤模块,就会越晚执行。

开发一个简单的过滤模块

要开发一个简单的过滤模块,它的功能是对Content-Type为text/plain的响应添加一个前缀,类似于开发一个HTTP模块,它应该遵循如下步骤:1.确定源代码文件名称,源代码所在目录创建config脚本文件,config文件的编写方式跟HTTP模块开发基本一致,不同的是需要将HTTP_MODULES改成HTTP_FILTER_MODULES.

2.定义过滤模块。实例化ngx_module_t类型模块结构,因为HTTP过滤模块也是HTTP模块,所以其中的type成员也是NGX_HTTP_MODULE.

3.处理感兴趣的配置项,通过设置ngx_module_t中的ngx_command_t数组来处理感兴趣的配置项。

4.实现初始化方法。初始化方法就是把本模块中处理HTTP头部的ngx_http_output_header_filter_pt方法和处理HTTP包体的ngx_http_output_body_filter_pt方法插入到过滤模块链表的首部。

5.实现4.中提到两个处理头部和包体的方法。

接下来按照上述步骤依次来实现:

2.1 确定源代码文件目录,编写config文件

config文件如下:ngx_addon_name=ngx_http_myfilter_module

HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_myfilter_module"

NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_myfilter_module.c"

2.2 定义过滤模块,实例化ngx_module_t/*定义过滤模块,ngx_module_t结构体实例化*/

ngx_module_t ngx_http_myfilter_module = {

NGX_MODULE_V1,      /*Macro*/

&ngx_http_myfilter_module_ctx,    /*module conte

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值