如何自定义配置项处理办法和合并

1自定义配置项处理方法

例子:

假设我们要处理的配置项名称是test_config,它接收1个或者2个参数,且第1个参数类型 是字符串,第2个参数必须是整型:

typedef struct {
ngx_str_t my_config_str;
ngx_int_t my_config_num;
} ngx_http_mytest_conf_t;

command的set方法

static char* ngx_conf_set_myconfig(ngx_conf_t cf, ngx_command_t cmd, void *conf)

自定义自己的结构体

static  ngx_conf_set_myconfig(ngx_conf_t cf,ngx_command_t cmd,void* conf)
{
    /*注意,参数conf就是HTTP框架传给用户的在ngx_http_mytest_create_loc_conf回调方法中
    分配的结构体ngx_http_mytest_conf_t*/
    ngx_http_mytest_conf_t mycf = conf;
    /* cf->args是1个ngx_array_t队列,它的成员都是ngx_str_t结构。我们用value指向ngx_array_t的
elts内容,其中value[1]就是第1个参数,同理,value[2]是第2个参数*/
    ngx_str_t value=cf->args->elts;

    if(cf->args->nlts>1)
    {
        mycf->my_config_str=value[1];
    }
    if(cf->args->nlts>2)
    {
      mycf->my_config_num = ngx_atoi(value[2].data, value[2].len);
      if(mycf->my_config_num == NGX_ERROR)
      {
        return "invaild number";      }
        
    }
    return NGX_CONF_OK;

参数解析:

1.参数conf就是HTTP框架传给用户的在ngx_http_mytest_create_loc_conf回调方法中分配的结构体ngx_http_mytest_conf_t(相当一座桥梁)

2.cf->args是1个ngx_array_t队列,它的成员都是ngx_str_t结构。我们用value指向ngx_array_t的
elts内容,其中value[1]就是第1个参数,同理,value[2]是第2个参数 (int main(char*arg....))

效果:

location{
      test_myconfig jordan 23;
}

my_config_str的值是jordan,而
my_config_num的值是23

合并配置项

背景:

一个test_str配置同时在http{...}、server{...}、location/url1{...} 中出现时,到底以哪一个为准?

下面是一个 ngx_http_module_t 结构:

typedef struct {
…
void (create_loc_conf)(ngx_conf_t cf);
char (*merge_loc_conf)(ngx_conf_t cf, void prev, void *conf);
…
} ngx_http_module_t;

1.上面这段代码定义了create_loc_conf方法,意味着HTTP框架会建立loc级别的配置

2.如果没有 merge函数 server块或者http块内出现的配置项都不会 生效。如果我们希望在server块或者http块内的配置项也生效,那么可以通过merge_loc_conf 方法来实现。merge_loc_conf会把所属父配置块的配置项与子配置块的同名配置项合并

解析

第1个参数仍然是ngx_conf_t*cf,提供一些基本的数据结构, 如内存池、日志等。第2、第3个参数

其中第2个参数void*prev是指解析 父配置块时生成的结构体,

而第3个参数void*conf则指出的是保存子配置块的结构体

示例:

static char *
ngx_http_mytest_merge_loc_conf(ngx_conf_t cf, void parent, void *child)
{
ngx_http_mytest_conf_t prev = (ngx_http_mytest_conf_t )parent;
ngx_http_mytest_conf_t conf = (ngx_http_mytest_conf_t )child;
ngx_conf_merge_str_value(conf->my_str,
prev->my_str, "defaultstr");
return NGX_CONF_OK;
}

1.引进一个宏ngx_conf_merge_str_value

#define ngx_conf_merge_str_value(conf, prev, default) \
// 当前配置块中是否已经解析到test_str配置项
if (conf.data == NULL){ 
// 父配置块中是否已经解析到test_str配置项
if (prev.data) { \
// 将父配置块中的
//test_str参数值直接覆盖当前配置块的test_str
conf.len = prev.len; \
conf.data = prev.data; \
} else { \
/*如果父配置块和子配置块都没有解析到
test_str,以
default参数作为默认值传给当前配置块的
test_str*/
conf.len = sizeof(default) - 1; \
conf.data = (u_char *) default; \
} \
}

2.效果

只需要按照自己的需求将父配置块的值赋予子配置块即可,这时表示父配置
块优先级更高

附录 关于十种配置项合并宏()

配置项合并宏意义
ngx_conf_merge_value合并可以使用等号(=)直接赋值的变量,并且该变量在 create_loc_conf等分配方法中初始化为NGX_CONF_UNSET,这样类型的成员可以使用ngx_conf_merge_value合并宏(预值处理项)
ngx_conf_merge ptr_value合并指针类型的变量,并且该变量在create_loc_conf等分配方法中初始化为NGX_CONF_UNSET_PTR,这样类型的成员可以使用ngx_conf_merge_ptr_value合并宏
ngx_conf_merge_uint_value合并整数类型的变量,并且该变量在create_loc_conf等分配方法中初始化为NGX_CONF_UNSET_UINT,这样类型的成员可以使用ngx_conf_merge_uint_value合并宏
ngx_conf_merge_msec_value合并表示毫秒的ngx_msec_t类型的变量,并且该变量在create_loc_conf等分配方法中初始化为NGX_CONF_UNSET_MSEC,这样类型的成员可以使用ngx_conf merge_msec_value合并宏
ngx_conf_merge_sec_value合并表示秒的time_t类型的变量,并且该变量在create_loc_conf等分配方法中初始化为NGX_CONF_UNSET,这样类型的成员可以使用ngx_conf_merge_sec_value合并宏
ngx_conf_merge_size_value合并size_t等表示空间长度的变量,并且该变量在 create_loc_conf等分配方法中初始化为NGX_CONF_UNSET_SIZE,这样类型的成员可以使用ngx_conf_merge_size_value合并宏
ngx_conf_merge_off_value合并off_t等表示偏移量的变量,并且该变量在create_loc_conf等分配方法中初始化为NGX_CONF_UNSET,这样类型的成员可以使用ngx_conf_merge_off_value合并宏
ngx_conf_merge_bufs_valuengx_bufs_t类型的成员可以使用ngx_conf_merge_bufs_value合并宏,这时传入的default参数是两个,因为ngx_bufs_t类型有两个成员,所以需要传入两个默认值
ngx_conf_merge_bitmask_value以二进制位来表示标志位的整型成员,可以使用ngx_conf_merge_bitmask_value合并宏

note:

参照1:一文读懂14种预设方法解析配置项_编程界的谢菲尔德的博客-CSDN博客

注意:除了ngx_conf_merge_bufs_value 外,它们都将接收3个参数,分别表示父配置块参数、子配置块参数、默认值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值