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

我编写了一个自定义的 nginx 模块,它需要 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 上下文中执行此操作。

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 模块?

点赞
用户2957719
用户2957719

所以做的方法是使用 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
}

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

ngx_http_netacuity_conf_t *nac = ngx_http_get_module_loc_conf(r, ngx_http_netacuity_module); //获取配置结构体
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

2016-06-07 21:08:37