[nginx源码分析]nginx filter模块解析

nginx filter分为header过滤链和body过滤链,这两天链是怎么形成的呢?在源文件ngx_http.c中,可以看到这两个函数指针变量

ngx_int_t  (*ngx_http_top_header_filter)(ngx_http_request_t* r)
ngx_int_t  (*ngx_http_top_body_filter)(ngx_http_request_t* r, ngx_chain_t* ch)

这是整个nginx范围内可见的全局变量。然后再每一个Filter模块内,我们都会看到类似于这样的定义

static  ngx_http_output_header_filter_pt 	ngx_http_next_header_filter;
static  ngx_http_output_body_filter_pt 	ngx_http_next_body_filter;

如果仅仅写一个header filter模块,那么仅仅有ngx_http_next_header_filter

如果仅仅写一个body filter模块,那么仅仅有ngx_http_next_body_filter;

如果两条链中都有过滤,那么就都定义。

 

一般我们都在postconfiguration进行设置,比如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;

}

因为配置解析完后,会遍历每一个模块的postconfiguration回调函数(针对ngx_http_header_filter_module来说,就是ngx_http_header_filter_init)。因为是依次遍历,那么这条链都是后面的模块在链表头,会先执行。


下面我们写一个filter的模块,主要功能很简单,如果content-length 超过1024字节,那么就把返回给客户端的状态码设置为404

config文件

ngx_addon_name=ngx_http_header_size_filter_module
HTTP_MODULES="$HTTP_MODULES ngx_http_header_size_filter_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_header_size_module.c"

ngx_http_header_size_module.c文件

/*
 * =====================================================================================
 *
 *       Filename:  ngx_http_header_size_module.c
 *
 *    Description:  一个nginx filter模块,如果发送的body超过了一定大小,那么就直接设置400错误
 *
 *        Version:  1.0
 *        Created:  05/04/2015 04:12:01 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  liyankun (), liyankun@baidu.com
 *   Organization:  
 *
 * =====================================================================================
 */

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

static ngx_int_t
ngx_http_header_size_filter(ngx_http_request_t *r);
static ngx_int_t
ngx_http_header_size_filter_init(ngx_conf_t* cf);

ngx_http_module_t  ngx_http_header_size_filter_module_ctx = {
    NULL,                                  /* preconfiguration */
    ngx_http_header_size_filter_init,       /* postconfiguration */

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */

    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */

    NULL,                                  /* create location configuration */
    NULL,                                  /* merge location configuration */
};


ngx_module_t  ngx_http_header_size_filter_module = {
    NGX_MODULE_V1,
    &ngx_http_header_size_filter_module_ctx, /* module context */
    NULL,                                  /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};

//定义一个static的next指针
static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;

//初始化函数,在配置解析完后
//此函数主要完成header函数过滤链的插入和衔接
static ngx_int_t ngx_http_header_size_filter_init(ngx_conf_t *cf)
{
    ngx_http_next_header_filter = ngx_http_top_header_filter;
    ngx_http_top_header_filter = ngx_http_header_size_filter;

    return NGX_OK;
}

/*
 * 如果说返回给用户的content_length超过1024那么就设置状态码为404
 */
static ngx_int_t
ngx_http_header_size_filter(ngx_http_request_t *r)
{
    if (r->headers_out.content_length_n > 1024)
    {
            r->headers_out.status = NGX_HTTP_NOT_FOUND;
    }
    return ngx_http_next_header_filter(r);
}


模块编译

./configure --prefix=/root/hunter/nginx/ngx_gdb --with-debug --with-cc-opt='-ggdb3 -O0' --with-pcre=/root/hunter/nginx/pcre-8.36--add-module=/root/hunter/nginx/nginx-1.2.0/src/module/read_module --add-module=/root/hunter/nginx/nginx-1.
2.0/src/module/header_size
make;make install

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值