• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Nginx HTTP过滤模块开发

php 搞代码 4年前 (2022-01-23) 31次浏览 已收录 0个评论

Nginx 过滤模块

HTTP过滤模块的开发步骤

  1. 确定源代码文件名称;
  2. 创建config脚本,当执行configure时将该目录添加进去;
  3. 定义过滤模块,实例化ngx_module_t类型的模块结构;
  4. 通过设置ngx_module_t结构中的ngx_command_t数组来处理感兴趣的配置项;
  5. 实现初始化函数,初始化方法就是将ngx_http_output_header_filter_t和ngx_http_output_body_filter_t函数插入到过滤模块链表的首部;
  6. 实现ngx_http_output_header_filter_pt和ngx_http_output_body_filter_pt函数;
  7. 编译安装后,修改nginx.conf配置文件中的过滤模块选项,开启与否。

配置脚本

<code>ngx_addHTTP_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"</span></code>

模块内容

<code><span>#include </span><span>#include </span><span>#include </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_tngx_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_tngx_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_tngx_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>"[m<em style="color:transparent">本@文来源[email protected]搞@^&代*@码网(</em><q>搞代gaodaima码</q>y filter module]"</span>);<span>//Filter to process the header</span><span>static</span> ngx_int_tngx_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_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);    <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>

配置文件nginx.conf

在http{}中加上
add_prefix on;
开启过滤模块

编译

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

HTTP过滤模块也是HTTP模块,所以HTTP模块的书写大致也是这样。

版权声明:Pain is just in your mind.

以上就介绍了Nginx HTTP过滤模块开发,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Nginx HTTP过滤模块开发

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址