将nginx变量作为命令行参数传递给nginx自定义模块

时间:2016-06-02 17:59:38

标签: nginx lua

我写了一个自定义的nginx模块,它接受3个命令行参数。我现在想将第3个参数作为nginx变量传递。但是,传递nginx变量会导致模块将变量名称作为参数读取。

这有效:

 custommodulename '4' '52.20.206.180' '1' ;

这不是:

    set $a '4';
    custommodulename '4' '52.20.206.180' a;

这也没有:

    set $a '4';
    custommodulename '4' '52.20.206.180' $a;

在上述两种情况下,模块都将第三个参数读作' a'而不是' 4' !

我想做什么: 我试图解析请求正文并将其中一个值传递给我的模块。 我在位置上下文中这样做。

location = /test1{
         client_max_body_size 100k;
        client_body_buffer_size 100k;
        lua_need_request_body on;
        set $a 'eeeeeeee';
        access_by_lua_block{
        package.cpath = package.cpath .. ";/usr/local/openresty/lualib/?.so";
        local cjson = require( "cjson" );  -- Include the Corona JSON library
        local body_table = cjson.decode(ngx.req.get_body_data());
        local name = body_table["username"];
        ngx.var.a = name;
        }
        echo $a;
        custommodulename '4' '52.20.206.180' a;
        echo "hi";
        echo $ip_address;
        }

curl的输出:

curl -H "Content-Type: application/json" -X POST -d '{"username":"152.134.20.1","password":"xyz"}' http://localhost:80/test1

152.134.20.1
hi

$ ip_address是我模块的变量保存结果。它没有打印,因为我的模块读取第三个参数为' a'因而引发错误。

如何将nginx变量作为参数传递给nginx模块?

1 个答案:

答案 0 :(得分:0)

所以要做的就是使用名为ngx_http_compile_complex_value_t的东西。基本上,您在模块配置结构中定义了ngx_http_complex_value_t类型的变量。

typedef struct {
    char *featureCode;
    char *netAcuityServerIp;
    char *ipaddress;
    ngx_http_complex_value_t *ipaddress;
} ngx_http_netacuity_conf_t;

调用自定义函数时,使用ngx_http_compile_complex_value设置作为变量传入的参数的值:

 static char *ngx_conf_set_str_custom(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_netacuity_conf_t *config = (ngx_http_netacuity_conf_t *)conf;
    ngx_http_compile_complex_value_t  ccv;

    ngx_str_t *value = cf->args->elts;

    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

    ccv.cf = cf;
    ccv.value = &value[3];
    ccv.complex_value = config->ipaddress;

    config->featureCode = (char *)(value[1].data);
    config->netAcuityServerIp = (char *)(value[2].data);
    //config->ipaddress = (char *)(value[3].data);
    if(ngx_http_compile_complex_value(&ccv) != NGX_OK) {
            return NGX_CONF_ERROR;
        } 
    return NGX_CONF_OK
}

将该值放入config结构中的变量中:

ngx_http_netacuity_conf_t *nac = ngx_http_get_module_loc_conf(r, ngx_http_netacuity_module); //get configuration struct
if (ngx_http_complex_value(r, nac->ipaddress, &query) != NGX_OK)
        {
             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,"ERROR");
        }

现在变量nac-> ipaddress具有作为变量参数传递给我的模块指令的值!!

我使用的链接:

http://www.nginxguts.com/2011/01/working-with-cookies/

https://github.com/openresty/redis2-nginx-module/blob/master/src/ngx_http_redis2_handler.c

https://github.com/openresty/redis2-nginx-module/blob/master/src/ngx_http_redis2_module.h