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


    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

  • 相关阅读:
    Linux中的mv命令详解
    ASP.NET问题处理---targetFramwork=‘4.0’错误
    Android----二维码开发
    android--HttpURLConnection(转载)
    SQL server 跨库插入数据
    AndroidStudio中 R文件缺失的办法
    ASP.NET程序如何更新发布
    Android切换页面--setContentView
    Android----service
    Android开发必备:颜色选择
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/16590185.html
Copyright © 2020-2023  润新知