IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    nginx模块开发(22)—conf常用函数

    cjhust发表于 2012-09-04 17:55:59
    love 0

    1、函数简介

    在研读nginx源代码的时候,发现nginx在处理conf的时候,经常会使用ngx_conf_set_off_slot、ngx_conf_set_msec_slot、ngx_conf_set_sec_slot、ngx_conf_set_bufs_slot、ngx_conf_set_enum_slot、ngx_conf_set_bitmask_slot等函数,为了以后的方便,现将以下函数仔细分析一遍。

    char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd,void *conf);

    char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    2、函数说明

    ngx_command_s

    struct ngx_command_s {

    ngx_str_t name;

    ngx_uint_t type;

    char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    ngx_uint_t conf;

    ngx_uint_t offset; //主要是存放转换后的值在配置结构体的偏移

    void *post;

    };

    ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似variables_hash_max_size 512这样的指令。

    char *

    ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_int_t *np;

    ngx_str_t *value;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    np = (ngx_int_t *) (p + cmd->offset);

    if (*np != NGX_CONF_UNSET) {

    return "is duplicate";

    }

    value = cf->args->elts;

    *np = ngx_atoi(value[1].data, value[1].len); //转化为整数

    if (*np == NGX_ERROR) {

    return "invalid number";

    }

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, np);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似client_body_timeout 60s/1d这样的指令。

    char *

    ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_msec_t *msp;

    ngx_str_t *value;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    msp = (ngx_msec_t *) (p + cmd->offset);

    if (*msp != NGX_CONF_UNSET_MSEC) {

    return "is duplicate";

    }

    value = cf->args->elts;

    *msp = ngx_parse_time(&value;[1], 0); //0表示以毫秒为单位

    if (*msp == (ngx_msec_t) NGX_ERROR) {

    return "invalid value";

    }

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, msp);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似ssl_session_timeout 30m/1d这样的指令。

    char *

    ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    time_t *sp;

    ngx_str_t *value;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    sp = (time_t *) (p + cmd->offset);

    if (*sp != NGX_CONF_UNSET) {

    return "is duplicate";

    }

    value = cf->args->elts;

    *sp = ngx_parse_time(&value;[1], 1); //1表示以秒为单位

    if (*sp == (time_t) NGX_ERROR) {

    return "invalid value";

    }

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, sp);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似client_body_buffer_size 512/512K/512M这样的指令。

    char *

    ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    size_t *sp;

    ngx_str_t *value;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    sp = (size_t *) (p + cmd->offset);

    if (*sp != NGX_CONF_UNSET_SIZE) {

    return "is duplicate";

    }

    value = cf->args->elts;

    *sp = ngx_parse_size(&value;[1]); //K/M,byte为默认单位

    if (*sp == (size_t) NGX_ERROR) {

    return "invalid value";

    }

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, sp);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似client_max_body_size 128K/128M/128G这样的指令。

    备注:ngx_conf_set_off_slot和ngx_conf_set_size_slot很相似,能看出的不同点就是ngx_conf_set_size_slot不支持G。

    char *

    ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    off_t *op;

    ngx_str_t *value;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    op = (off_t *) (p + cmd->offset);

    if (*op != NGX_CONF_UNSET) {

    return "is duplicate";

    }

    value = cf->args->elts;

    *op = ngx_parse_offset(&value;[1]); //K/M/G

    if (*op == (off_t) NGX_ERROR) {

    return "invalid value";

    }

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, op);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似daemon off/on这样的指令。

    char *

    ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_str_t *value;

    ngx_flag_t *fp;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    fp = (ngx_flag_t *) (p + cmd->offset);

    if (*fp != NGX_CONF_UNSET) {

    return "is duplicate";

    }

    value = cf->args->elts;

    if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {

    *fp = 1;

    } else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {

    *fp = 0;

    } else {

    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,

    "invalid value \"%s\" in \"%s\" directive, "

    "it must be \"on\" or \"off\"",

    value[1].data, cmd->name.data);

    return NGX_CONF_ERROR;

    }

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, fp);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似pid logs/nginx.pid这样的指令。

    char *

    ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_str_t *field, *value;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    field = (ngx_str_t *) (p + cmd->offset);

    if (field->data) {

    return "is duplicate";

    }

    value = cf->args->elts;

    *field = value[1];

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, field);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似large_client_header_buffers 4 2k这样的指令。

    char *

    ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_str_t *value;

    ngx_bufs_t *bufs;

    // offset主要是存放转换后的值在配置结构体的偏移

    bufs = (ngx_bufs_t *) (p + cmd->offset);

    if (bufs->num) {

    return "is duplicate";

    }

    value = cf->args->elts;

    //第一个参数,整数

    bufs->num = ngx_atoi(value[1].data, value[1].len);

    if (bufs->num == NGX_ERROR || bufs->num == 0) {

    return "invalid value";

    }

    //第二个参数,size

    bufs->size = ngx_parse_size(&value;[2]);

    if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) {

    return "invalid value";

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    image

    函数功能:处理类似proxy_http_version 1.1这样的指令。

    char *

    ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_uint_t *np, i;

    ngx_str_t *value;

    ngx_conf_enum_t *e;

    // offset主要是存放转换后的值在配置结构体的偏移

    np = (ngx_uint_t *) (p + cmd->offset);

    if (*np != NGX_CONF_UNSET_UINT) {

    return "is duplicate";

    }

    value = cf->args->elts;

    e = cmd->post;

    //需要和cmd->post里的数据进行对比

    for (i = 0; e[i].name.len != 0; i++) {

    if (e[i].name.len != value[1].len

    || ngx_strcasecmp(e[i].name.data, value[1].data) != 0)

    {

    continue;

    }

    *np = e[i].value;

    return NGX_CONF_OK;

    }

    ngx_conf_log_error(NGX_LOG_WARN, cf, 0,

    "invalid value \"%s\"", value[1].data);

    return NGX_CONF_ERROR;

    }

    ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    clip_image002

    clip_image004

    函数功能:处理类似proxy_next_upstream error timeout http_502 http_503 http_504这样的指令。

    char *

    ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_uint_t *np, i, m;

    ngx_str_t *value;

    ngx_conf_bitmask_t *mask;

    // offset主要是存放转换后的值在配置结构体的偏移

    np = (ngx_uint_t *) (p + cmd->offset);

    value = cf->args->elts;

    mask = cmd->post;

    //需要跟cmd->post里的数据进行对比

    for (i = 1; i < cf->args->nelts; i++) {

    for (m = 0; mask[m].name.len != 0; m++) {

    if (mask[m].name.len != value[i].len

    || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)

    {

    continue;

    }

    if (*np & mask[m].mask) {

    ngx_conf_log_error(NGX_LOG_WARN, cf, 0,

    "duplicate value \"%s\"", value[i].data);

    } else {

    *np |= mask[m].mask;

    }

    break;

    }

    if (mask[m].name.len == 0) {

    ngx_conf_log_error(NGX_LOG_WARN, cf, 0,

    "invalid value \"%s\"", value[i].data);

    return NGX_CONF_ERROR;

    }

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    image

    函数功能:处理类似proxy_set_header ORIG_CLIENT_IP $remote_addr这样的指令。

    char *

    ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ngx_str_t *value;

    ngx_array_t **a;

    ngx_keyval_t *kv;

    ngx_conf_post_t *post;

    // offset主要是存放转换后的值在配置结构体的偏移

    a = (ngx_array_t **) (p + cmd->offset);

    if (*a == NULL) {

    *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));

    if (*a == NULL) {

    return NGX_CONF_ERROR;

    }

    }

    kv = ngx_array_push(*a);

    if (kv == NULL) {

    return NGX_CONF_ERROR;

    }

    value = cf->args->elts;

    kv->key = value[1];

    kv->value = value[2];

    if (cmd->post) {

    post = cmd->post;

    return post->post_handler(cf, post, kv);

    }

    return NGX_CONF_OK;

    }

    ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    image

    函数功能:处理类似client_body_temp_path /spool/nginx/client_temp 1 2这样的指令。

    char *

    ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    {

    char *p = conf;

    ssize_t level;

    ngx_str_t *value;

    ngx_uint_t i, n;

    ngx_path_t *path, **slot;

    // offset主要是存放转换后的值在配置结构体的偏移

    slot = (ngx_path_t **) (p + cmd->offset);

    if (*slot) {

    return "is duplicate";

    }

    path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));

    if (path == NULL) {

    return NGX_CONF_ERROR;

    }

    value = cf->args->elts;

    path->name = value[1];

    if (path->name.data[path->name.len - 1] == '/') {

    path->name.len--;

    }

    if (ngx_conf_full_name(cf->cycle, &path-;>name, 0) != NGX_OK) {

    return NULL;

    }

    path->len = 0;

    path->manager = NULL;

    path->loader = NULL;

    path->conf_file = cf->conf_file->file.name.data;

    path->line = cf->conf_file->line;

    for (i = 0, n = 2; n < cf->args->nelts; i++, n++) {

    level = ngx_atoi(value[n].data, value[n].len);

    if (level == NGX_ERROR || level == 0) {

    return "invalid value";

    }

    path->level[i] = level;

    path->len += level + 1;

    }

    while (i < 3) {

    path->level[i++] = 0;

    }

    *slot = path;

    if (ngx_add_path(cf, slot) == NGX_ERROR) {

    return NGX_CONF_ERROR;

    }

    return NGX_CONF_OK;

    }



沪ICP备19023445号-2号
友情链接