ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

nginx ngx_http_addition_module 模块openresty content_by_lua 不能生效的原因

2022-08-16 00:32:23  阅读:239  来源: 互联网

标签:body http addition module filter lua openresty ngx


nginx 的ngx_http_addition_module 模块也是一个修改content 的好东西,对于openresty 我们经常使用content_by_lua 阶段处理
但是经过分析ngx_http_addition_module 源码的处理机制,他是基于body_fiter 处理的,所以我们基于content_by_lua 进行数据处理
会有顺序不对的问题

参考源码处理

处理机制
ngx_http_addition_filter_module_ctx上下文定义

 
static ngx_http_module_t  ngx_http_addition_filter_module_ctx = {
    NULL,                                  /* preconfiguration */
    ngx_http_addition_filter_init,         /* postconfiguration */
 
    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */
 
    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */
 
    ngx_http_addition_create_conf,         /* create location configuration */
    ngx_http_addition_merge_conf           /* merge location configuration */
};

阶段(依赖了header 以及body)

static ngx_int_t
ngx_http_addition_filter_init(ngx_conf_t *cf)
{
    ngx_http_next_header_filter = ngx_http_top_header_filter;
    ngx_http_top_header_filter = ngx_http_addition_header_filter;
 
    ngx_http_next_body_filter = ngx_http_top_body_filter;
    ngx_http_top_body_filter = ngx_http_addition_body_filter;
 
    return NGX_OK;
}

核心处理

static ngx_int_t
ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    ngx_int_t                  rc;
    ngx_uint_t                 last;
    ngx_chain_t               *cl;
    ngx_http_request_t        *sr;
    ngx_http_addition_ctx_t   *ctx;
    ngx_http_addition_conf_t  *conf;
 
    if (in == NULL || r->header_only) {
        return ngx_http_next_body_filter(r, in);
    }
 
    ctx = ngx_http_get_module_ctx(r, ngx_http_addition_filter_module);
 
    if (ctx == NULL) {
        return ngx_http_next_body_filter(r, in);
    }
 
    conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
 
    if (!ctx->before_body_sent) {
        ctx->before_body_sent = 1;
 
        if (conf->before_body.len) {
            if (ngx_http_subrequest(r, &conf->before_body, NULL, &sr, NULL, 0)
                != NGX_OK)
            {
                return NGX_ERROR;
            }
        }
    }
 
    if (conf->after_body.len == 0) {
        ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module);
        return ngx_http_next_body_filter(r, in);
    }
 
    last = 0;
 
    for (cl = in; cl; cl = cl->next) {
        if (cl->buf->last_buf) {
            cl->buf->last_buf = 0;
            cl->buf->last_in_chain = 1;
            cl->buf->sync = 1;
            last = 1;
        }
    }
 
    rc = ngx_http_next_body_filter(r, in);
 
    if (rc == NGX_ERROR || !last || conf->after_body.len == 0) {
        return rc;
    }
    if (ngx_http_subrequest(r, &conf->after_body, NULL, &sr, NULL, 0)
        != NGX_OK)
    {
        return NGX_ERROR;
    }
 
    ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module);
 
    return ngx_http_send_special(r, NGX_HTTP_LAST);
}

如果需要使用的解决方法

可以直接在body_fiter 阶段进行数据处理,注意此阶段会有一些api 的限制
参考处理(直接输出了,比较简单)

 
location = /flush2.html {
    add_before_body /before_action;
    add_after_body  /after_action;
}
location  /before_action {
    default_type text/html;
    content_by_lua_block {
            ngx.say("this is before content\n")
            ngx.log(ngx.ERR, "before_action")
    }
}
location  /after_action {
    default_type text/html;
    body_filter_by_lua_block {
              ngx.arg[1] = "this is after content\n"
    }
}

说明

以上是结合源码学习ngx_http_addition_module 与openresty 集成的处理,大家如果碰到类似问题可以参考

参考资料

https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_addition_filter_module.c#L133

标签:body,http,addition,module,filter,lua,openresty,ngx
来源: https://www.cnblogs.com/rongfengliang/p/16590185.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有