首先我们在nginx.conf里设置一个自定义的变量,例如
location /wyx {
set $sean_key "12214";
}
这里我们用了set指令,set指令是ngx_http_rewrite_module模块提供给我们的一个指令。它的作用就是给变量设置一个值。
这里我们给变量sean_key赋值为"12214"。但是sean_key不是内置变量,nginx并不能识别变量名sean_key,我们在nginx里自己写一个模块里要使用这个值就需要使用ngx_http_add_variable和ngx_http_get_indexed_variable函数了。
示例代码如下,首先我们在模块的配置阶段添加这个变量,这里可以在ngx_sean_block里调用sean_add_indexed_variable,变量名sean_key和上面的set指令的变量名保持一致。得到的变量索引保存在sean_cf->sean_key_index里。
typedef struct /*ngx_sean_conf_s*/ {
//自定义变量
ngx_int_t sean_key_index;//变量索引
} ngx_sean_conf_t;
...
static ngx_command_t ngx_sean_commands[] = {
{ ngx_string("sean"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE4|NGX_CONF_TAKE5, //type NGX_CONF_NOARGS 标识后面不带参数 NGX_CONF_TAKE4 标识后面可以带4个参数
ngx_sean_block, //在ngx_sean_block里调用sean_add_indexed_variable创建 变量
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
ngx_null_command
};
...
static ngx_int_t sean_add_indexed_variable(ngx_conf_t *cf)
{
ngx_sean_conf_t* sean_cf;
sean_cf = (ngx_sean_conf_t*)ngx_http_conf_get_module_loc_conf(cf, ngx_sean_module); //获取的是ngx_sean_module的配置
//变量名称sean_key
ngx_str_t ngx_http_sean_key = ngx_string("sean_key");
//使用ngx_http_sean_add_variable添加一个名为sean_key的变量
sean_cf->sean_key_index = ngx_http_sean_add_variable(cf, &ngx_http_sean_key);
if (sean_cf->sean_key_index == NGX_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "ngx_http_sean_postconfiguration sean_cf->sean_key_index == NGX_ERROR");
return NGX_ERROR;
}
ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "ngx_http_sean_postconfiguration sean_cf->sean_key_index==%d, sean_cf %p"
, sean_cf->sean_key_index, sean_cf);
return NGX_OK;
}
...
static char *ngx_sean_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) //conf是ngx_http_sean_create_loc_conf返回的ngx_sean_conf_t
{
//自定义变量
sean_add_indexed_variable(cf);
return NGX_CONF_OK;
}
接下来就是使用了,上面我们添加了变量,并得到了他的索引sean_key_index,下面就通过sean_key_index来调用ngx_http_get_indexed_variable来得到变量,把变量存到了字符串ngx_str_t sean_key里。
//自定义变量
static ngx_int_t sean_indexed_variable(ngx_http_request_t *r, ngx_sean_conf_t* sean_cf)
{
ngx_http_variable_value_t *key_vv;
key_vv = ngx_http_get_indexed_variable(r, sean_cf->sean_key_index);
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0
, "sean_indexed_variable sean_key_index %d, key_vv %p, sean_cf %p", sean_cf->sean_key_index, key_vv, sean_cf);
if (key_vv == NULL) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0
, "sean_indexed_variable NGX_HTTP_INTERNAL_SERVER_ERROR");
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if(key_vv->not_found||key_vv->len==0)
{
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0
, "sean_indexed_variable key_vv->not_found %d, key_vv->len %d", key_vv->not_found, key_vv->len);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
//变量值保存到了字符串里
ngx_str_t sean_key;
sean_key.data = key_vv->data;
sean_key.len = key_vv->len;
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0
, "sean_indexed_variable sean_key=%V", &sean_key);
return NGX_OK;
}
curl http://127.0.0.1:8881/wyx?key=42,在日志里查看运行结果如下,sean_key=12214,和我们在nginx.conf里设置的一样
2021/12/08 16:16:20 [alert] 29057#0: *2 sean_indexed_variable sean_key=12214, client: 127.0.0.1, server: localhost, request: "GET /wyx?key=42 HTTP/1.1", host: "127.0.0.1:8881"
最后,在下面连接的这篇文章的最后,讲了一下自定义变量和内置变量结合使用的方式,有兴趣可以看看nginx里ngx_http_compile_complex_value和ngx_http_complex_value的初步使用_wwyyxx26的专栏-CSDN博客