nginx 过滤模块
http过滤模块的开发步骤
确定源代码文件名称;创建config脚本,当执行configure时将该目录添加进去;定义过滤模块,实例化ngx_module_t类型的模块结构;通过设置ngx_module_t结构中的ngx_command_t数组来处理感兴趣的配置项;实现初始化函数,初始化方法就是将ngx_http_output_header_filter_t和ngx_http_output_body_filter_t函数插入到过滤模块链表的首部;实现ngx_http_output_header_filter_pt和ngx_http_output_body_filter_pt函数;编译安装后,修改nginx.conf配置文件中的过滤模块选项,开启与否。配置脚本
ngx_addhttp_filter_modules=$http_filter_modules ngx_http_myfilter_modulengx_add>$ngx_addon_srcs$ngx_addon_dir/ngx_http_myfilter_module.c
模块内容
#include #include #include //declarestatic ngx_int_t ngx_http_myfilter_header_filter(ngx_http_request_t *);static ngx_int_t ngx_http_myfilter_body_filter(ngx_http_request_t*,ngx_chain_t*);static ngx_http_output_header_filter_pt ngx_http_next_header_filter;static ngx_http_output_body_filter_pt ngx_http_next_body_filter;//on/offtypedefstruct { ngx_flag_t enable;}ngx_http_myfilter_conf_t;staticvoid *ngx_http_myfilter_create_conf(ngx_conf_t *cf){ ngx_http_myfilter_conf_t *mycf; //allocate memory mycf = (ngx_http_myfilter_conf_t*)ngx_pcalloc(cf->pool,sizeof(ngx_http_myfilter_conf_t)); if(mycf == null) returnnull; mycf->enable = ngx_conf_unset; return mycf;}staticchar *ngx_http_myfilter_merge_conf(ngx_conf_t *cf,void *parent,void *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,0); return ngx_conf_ok;}/* ------------------------------------------- *///state for prefixtypedefstruct { /* add_prefix = * 0 the filter module is off * 1 can add prefix * 2 has been added prefix already */ ngx_int_t add_prefix;} ngx_http_myfilter_ctx_t;//analyse configurestatic ngx_command_tngx_http_myfilter_commands[]={ {ngx_string(add_prefix), 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), null}, ngx_null_command};static ngx_int_tngx_http_myfilter_init(ngx_conf_t *cf){ //insert before the first node 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; return ngx_ok;}/* ------------------------------------------- *///parsestatic ngx_http_module_tngx_http_myfilter_module_ctx = { null, ngx_http_myfilter_init, null, null, null, null, ngx_http_myfilter_create_conf, ngx_http_myfilter_merge_conf};/* ------------------------------------------- *///module informationngx_module_t ngx_http_myfilter_module = { ngx_module_v1, &ngx_http_myfilter_module_ctx, ngx_http_myfilter_commands, ngx_http_module, null, null, null, null, null, null, null, ngx_module_v1_padding};/* ------------------------------------------- */static ngx_str_t filter_prefix = ngx_string([my filter module]);//filter to process the headerstatic ngx_int_tngx_http_myfilter_header_filter(ngx_http_request_t *r){ ngx_http_myfilter_ctx_t *ctx; ngx_http_myfilter_conf_t *conf; if(r->headers_out.status != ngx_http_ok){ return ngx_http_next_header_filter(r); } //get context ctx = ngx_http_get_module_ctx(r,ngx_http_myfilter_module); if(ctx){ return ngx_http_next_header_filter(r); } //get configure by ngx_http_myfilter_conf_t conf = ngx_http_get_module_loc_conf(r,ngx_http_myfilter_module); if(conf->enable == 0){//add_prefix offreturn ngx_http_next_header_filter(r); } //create ngx_http_myfilter_ctx_t ctx = ngx_pcalloc(r->pool,sizeof(ngx_http_myfilter_ctx_t)); if(ctx == null){ return ngx_error; } //add_prefix = 0 express do not add prefix ctx->add_prefix = 0; //set context ngx_http_set_ctx(r,ctx,ngx_http_myfilter_module); //myfilter module only figure out content-type=text/plainif(r->headers_out.content_type.len>=sizeof(text/plain) - 1 && ngx_strncasecmp(r->headers_out.content_type.data,(u_char*)text/plain,sizeof(text/plain)-1)==0){ //set add_prefix ctx->add_prefix = 1; if(r->headers_out.content_length_n>0) r->headers_out.content_length_n += filter_prefix.len; } return ngx_http_next_header_filter(r);}//filter to process the bodystatic ngx_int_tngx_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); //if cannot get context or the add_prefix is 0/2,do not processif(ctx == null || ctx->add_prefix !=1) return ngx_http_next_body_filter(r,in); //to make sure never add prefix again ctx->add_prefix = 2; //get prefix string ngx_buf_t *b = ngx_create_temp_buf(r->pool,filter_prefix.len); b->start = b->pos = filter_prefix.data; b->last = b->pos + filter_prefix.len; //get and set ngx_chain_t list at the bginning ngx_chain_t *cl = ngx_alloc_chain_link(r->pool); cl->buf = b; cl->next = in; return ngx_http_next_body_filter(r,cl);}
配置文件nginx.conf
在http{}中加上
add_prefix on;
开启过滤模块
编译
./configure --add-module=模块路径/makemake install
http过滤模块也是http模块,所以http模块的书写大致也是这样。
版权声明:pain is just in your mind.
以上就介绍了nginx http过滤模块开发,包括了方面的内容,希望对php教程有兴趣的朋友有所帮助。