[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 (), [email protected]
 *   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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章