nginx模块在指令中扩展变量的最佳方法是什么?

时间:2017-04-07 23:01:42

标签: c nginx module

假设我正在编写一个nginx模块,该模块在位置块中声明了一些指令mymod_opt,并且用户编写如下内容:

location / {
  mymod_opt $uri;
  ...
}

模块扩展任何变量的最佳方式是什么,以便它与实际的uri而不是ngx_str_t获得"$uri"

1 个答案:

答案 0 :(得分:3)

看起来最好的方法是将变量视为脚本,在首次处理编译时使用函数ngx_http_script_compile,并在调用模块时调用ngx_http_script_run变量。以下是如何设置它的示例:

在模块的本地配置中添加变量以存储编译脚本。

struct ngx_http_mymod_loc_conf_t {
  ngx_array_t* opt_lengths;
  ngx_array_t* opt_values;
};

在命令数组中指定在遇到指令时运行自定义函数。

static ngx_command_t ngx_http_mymod_commands[] = {
  {
    ngx_string("mymod_opt"),
    NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1, 
    ngx_http_mymod_opt,
    NGX_HTTP_LOC_CONF_OFFSET, 
    0, 
    NULL
  },
  ...
}

添加编译脚本的函数

static char *ngx_http_mymod_opt(ngx_conf_t *cf, ngx_command_t *command,
                                void *conf) {
  ngx_http_mymod_loc_conf_t *loc_conf;
  ngx_str_t *value;
  ngx_str_t *mymod_opt;
  ngx_http_script_compile_t script_compile;

  loc_conf = conf;
  value = cf->args->elts;
  mymod_opt = &value[1];

  ngx_memzero(&script_compile, sizeof(ngx_http_script_compile_t));
  script_compile.cf = cf;
  script_compile.source = mymod_opt;
  script_compile.lengths = &loc_conf->mymod_opt_lengths;
  script_compile.values = &loc_conf->mymod_opt_values;
  script_compile.variables = ngx_http_script_variables_count(mymod_opt);
  script_compile.complete_lengths = 1;
  script_compile.complete_values = 1;

  if (ngx_http_script_compile(&script_compile) != NGX_OK) return NGX_CONF_ERROR;

  return NGX_CONF_OK;
}

然后可以使用此函数调用扩展变量:

ngx_str_t result;
ngx_http_script_run(request, &result, loc_conf->lengths->elts, 0, 
                    loc_conf->values->elts)