>  기사  >  백엔드 개발  >  Nginx HTTP 필터 모듈 개발

Nginx HTTP 필터 모듈 개발

WBOY
WBOY원래의
2016-08-08 09:20:181076검색

Nginx 필터 모듈

HTTP 필터 모듈 개발 단계

  1. 소스 코드 파일 이름을 결정합니다.
  2. 구성 스크립트를 생성합니다. 실행됨
  3. 필터 모듈을 정의하고 ngx_module_t 유형의 모듈 구조를 인스턴스화합니다.
  4. ngx_module_t 구조에서 ngx_command_t 배열을 설정하여 관심 있는 구성 항목을 처리합니다. 🎜>초기화 기능을 구현합니다. 초기화 방법은 필터 모듈 연결 목록의 헤드에 ngx_http_output_header_filter_t 및 ngx_http_output_body_filter_t 함수를 삽입하는 것입니다.
  5. ngx_http_output_header_filter_pt 및 ngx_http_output_body_filter_pt 함수를 구현합니다. 🎜>컴파일 후 설치, nginx .conf 구성 파일 수정 의 필터 모듈 옵션(활성화 여부).
  6. 구성 스크립트

모듈 콘텐츠

<code>ngx_add

HTTP_FILTER_MODULES=<span>"<span>$HTTP_FILTER_MODULES</span> ngx_http_myfilter_module"</span>
NGX_ADD>"<span>$NGX_ADDON_SRCS</span><span>$ngx_addon_dir</span>/ngx_http_myfilter_module.c"</code>
http의 nginx.conf

구성 파일{} 추가
<code><span>#include <../src/core/ngx_config.h></span><span>#include <../src/core/ngx_core.h></span><span>#include <../src/http/ngx_http.h></span><span>//Declare</span><span>static</span> ngx_int_t ngx_http_myfilter_header_filter(ngx_http_request_t *);
<span>static</span> ngx_int_t ngx_http_myfilter_body_filter(ngx_http_request_t*,ngx_chain_t*);
<span>static</span> ngx_http_output_header_filter_pt ngx_http_next_header_filter;
<span>static</span> ngx_http_output_body_filter_pt ngx_http_next_body_filter;


<span>//On/Off</span><span>typedef</span><span>struct</span> {
    ngx_flag_t enable;
}ngx_http_myfilter_conf_t;

<span>static</span><span>void</span> *ngx_http_myfilter_create_conf(ngx_conf_t *cf){
    ngx_http_myfilter_conf_t *mycf;

    <span>//Allocate memory</span>
    mycf = (ngx_http_myfilter_conf_t*)ngx_pcalloc(cf->pool,<span>sizeof</span>(ngx_http_myfilter_conf_t));
    <span>if</span>(mycf == <span>NULL</span>)
        <span>return</span><span>NULL</span>;

    mycf->enable = NGX_CONF_UNSET;

    <span>return</span> mycf;
}

<span>static</span><span>char</span> *
ngx_http_myfilter_merge_conf(ngx_conf_t *cf,<span>void</span> *parent,<span>void</span> *child){
    ngx_http_myfilter_conf_t *prev = (ngx_http_myfilter_conf_t*)parent;
    ngx_http_myfilter_conf_t *conf = (ngx_http_myfilter_conf_t*)child;
    ngx_conf_merge_value(conf->enable,prev->enable,<span>0</span>);
    <span>return</span> NGX_CONF_OK;
}

<span>/* ------------------------------------------- */</span><span>//State for prefix</span><span>typedef</span><span>struct</span> {
    <span>/* add_prefix = 
     * 0    the filter module is off
     * 1    can add prefix
     * 2    has been added prefix already
     */</span>
    ngx_int_t add_prefix;
} ngx_http_myfilter_ctx_t;

<span>//Analyse configure</span><span>static</span> ngx_command_t
ngx_http_myfilter_commands[]={
    {ngx_string(<span>"add_prefix"</span>),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_FLAG,
        ngx_conf_set_flag_slot,
        NGX_HTTP_LOC_CONF_OFFSET,
        offsetof(ngx_http_myfilter_conf_t,enable),
        <span>NULL</span>},
    ngx_null_command
};

<span>static</span> ngx_int_t
ngx_http_myfilter_init(ngx_conf_t *cf){
    <span>//Insert before the first node</span>
    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;

    <span>return</span> NGX_OK;
}

<span>/* ------------------------------------------- */</span><span>//Parse</span><span>static</span> ngx_http_module_t
ngx_http_myfilter_module_ctx = {
    <span>NULL</span>,
    ngx_http_myfilter_init,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    ngx_http_myfilter_create_conf,
    ngx_http_myfilter_merge_conf
};

<span>/* ------------------------------------------- */</span><span>//Module information</span>
ngx_module_t ngx_http_myfilter_module = {
    NGX_MODULE_V1,
    &ngx_http_myfilter_module_ctx,
    ngx_http_myfilter_commands,
    NGX_HTTP_MODULE,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    <span>NULL</span>,
    NGX_MODULE_V1_PADDING
};

<span>/* ------------------------------------------- */</span><span>static</span> ngx_str_t filter_prefix = ngx_string(<span>"[my filter module]"</span>);

<span>//Filter to process the header</span><span>static</span> ngx_int_t
ngx_http_myfilter_header_filter(ngx_http_request_t *r){
    ngx_http_myfilter_ctx_t *ctx;
    ngx_http_myfilter_conf_t *conf;

    <span>if</span>(r->headers_out<span>.status</span> != NGX_HTTP_OK){
        <span>return</span> ngx_http_next_header_filter(r);
    }

    <span>//Get context</span>
    ctx = ngx_http_get_module_ctx(r,ngx_http_myfilter_module);
    <span>if</span>(ctx){
        <span>return</span> ngx_http_next_header_filter(r);
    }

    <span>//Get configure by ngx_http_myfilter_conf_t</span>
    conf = ngx_http_get_module_loc_conf(r,ngx_http_myfilter_module);

    <span>if</span>(conf->enable == <span>0</span>){<span>//add_prefix off</span><span>return</span> ngx_http_next_header_filter(r);
    }

    <span>//Create ngx_http_myfilter_ctx_t</span>
    ctx = ngx_pcalloc(r->pool,<span>sizeof</span>(ngx_http_myfilter_ctx_t));
    <span>if</span>(ctx == <span>NULL</span>){
        <span>return</span> NGX_ERROR;
    }

    <span>//add_prefix = 0 express do not add prefix</span>
    ctx->add_prefix = <span>0</span>;

    <span>//Set context</span>
    ngx_http_set_ctx(r,ctx,ngx_http_myfilter_module);

    <span>//myfilter module only figure out Content-Type="text/plain"</span><span>if</span>(r->headers_out<span>.content_type</span><span>.len</span>>=<span>sizeof</span>(<span>"text/plain"</span>) - <span>1</span> &&
            ngx_strncasecmp(r->headers_out<span>.content_type</span><span>.data</span>,(u_char*)<span>"text/plain"</span>,<span>sizeof</span>(<span>"text/plain"</span>)-<span>1</span>)==<span>0</span>){
        <span>//Set add_prefix</span>
        ctx->add_prefix = <span>1</span>;
        <span>if</span>(r->headers_out<span>.content_length_n</span>><span>0</span>)
            r->headers_out<span>.content_length_n</span> += filter_prefix<span>.len</span>;
    }
        <span>return</span> ngx_http_next_header_filter(r);
}

<span>//Filter to process the body</span><span>static</span> ngx_int_t
ngx_http_myfilter_body_filter(ngx_http_request_t *r,ngx_chain_t *in){
    ngx_http_myfilter_ctx_t *ctx;
    ctx = ngx_http_get_module_ctx(r,ngx_http_myfilter_module);
    <span>//If cannot get context or the add_prefix is 0/2,do not process</span><span>if</span>(ctx == <span>NULL</span> || ctx->add_prefix !=<span>1</span>)
        <span>return</span> ngx_http_next_body_filter(r,in);

    <span>//To make sure never add prefix again</span>
    ctx->add_prefix = <span>2</span>;

    <span>//Get prefix string</span>
    ngx_buf_t *b = ngx_create_temp_buf(r->pool,filter_prefix<span>.len</span>);
    b->start = b->pos = filter_prefix<span>.data</span>;
    b->last = b->pos + filter_prefix<span>.len</span>;

    <span>//Get and set ngx_chain_t list at the bginning</span>
    ngx_chain_t *cl = ngx_alloc_chain_link(r->pool);
    cl->buf = b;
    cl->next = in;

    <span>return</span> ngx_http_next_body_filter(r,cl);
}</code>
추가_접두사

필터링 모듈 활성화

컴파일

HTTP 필터링 모듈도 HTTP 모듈이므로 HTTP 모듈 작성은 거의 동일합니다.

<code>./configure --<span>add</span>-<span>module</span>=模块路径/
make
make install</code>

저작권: 고통은 마음속에 있는 것입니다.

위에서는 Nginx HTTP 필터링 모듈의 개발과 그 측면을 소개했습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.