nginx 指令中变量处理
指令参数都是常量
对于nginx的指令来说,如果指令的参数都是常量,解析这些参数就比较容易了,使用nginx自带的ngx_conf_set_xxx_slot函数,或者自定义解析函数都很容易解析配置。随便举两个例子如下:
ngx_conf_set_off_slot
ngx_conf_set_size_slot
ngx_conf_set_msec_slot
指令参数是变量
但是如果指令中输入的参数是变量,那么该如何处理呢?
比如:
ngx_test_cmd $file $pos
先介绍如下方式解析配置
会使用nginx如下两个关于变量的函数,当然还有其他的,为了好说明就用这两个。
ngx_int_t ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name);
ngx_http_variable_value_t *ngx_http_get_indexed_variable(ngx_http_request_t *r,ngx_uint_t index);
具体的使用过程:
模块名为: ngx_test_module
1、在自定义的conf结构体中,添加一个索引变量
typedef struct {
ngx_int_t file_index;
ngx_int_t pos_index;
}ngx_test_conf_t;
- 定义操作conf的command如下
{ ngx_string("ngx_test_cmd"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2
ngx_http_test_cmd,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
- ngx_test_cmd指令对应的处理函数
static char *
ngx_http_test_cmd(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_test_conf_t *tcf = conf;
ngx_str_t *value, filename, pos;
value = cf->args->elts;
/*filename index*/
filename = value[1];
if (filename.data[0] != '$') {
return "invalid filename variable";
}
filename.len--;
filename.data++;
tcf->file_index = ngx_http_get_variable_index(cf, &filename);
if (tcf->file_index == NGX_ERROR) {
return NGX_CONF_ERROR;
}
/*pos index*/
pos = value[2];
if (pos.data[0] != '$') {
return "invalid pos variable";
}
pos.len--;
pos.data++;
tcf->pos_index = ngx_http_get_variable_index(cf, &pos);
if (tcf->pos_index == NGX_ERROR) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
- 在filter或者其他阶段需要获取变量具体值的时候
ngx_variable_value_t *filename, *pos;
tcf = ngx_http_get_module_loc_conf(r, ngx_test_module);
if (tcf->file_index != -1) {
filename = ngx_http_get_flushed_variable(r, tcf->file_index);
if (filename == NULL || filename->not_found) {
return NGX_ERROR;
}
}
if (tcf->pos_index != -1) {
pos = ngx_http_get_flushed_variable(r, tcf->pos_index);
if (pos == NULL || pos->not_found) {
return NGX_ERROR;
}
}
- 这样文件名就存储在filename里,而文件偏移量就在pos里了。
变量的第一种取值方法就说这么多。