当前位置: 首页 > article >正文

ngx_http_compile_complex_value

定义在 src\http\ngx_http_script.c

ngx_int_t
ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
{
    ngx_str_t                  *v;
    ngx_uint_t                  i, n, nv, nc;
    ngx_array_t                 flushes, lengths, values, *pf, *pl, *pv;
    ngx_http_script_compile_t   sc;

    v = ccv->value;

    nv = 0;
    nc = 0;

    for (i = 0; i < v->len; i++) {
        if (v->data[i] == '$') {
            if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
                nc++;

            } else {
                nv++;
            }
        }
    }

    if ((v->len == 0 || v->data[0] != '$')
        && (ccv->conf_prefix || ccv->root_prefix))
    {
        if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
            return NGX_ERROR;
        }

        ccv->conf_prefix = 0;
        ccv->root_prefix = 0;
    }

    ccv->complex_value->value = *v;
    ccv->complex_value->flushes = NULL;
    ccv->complex_value->lengths = NULL;
    ccv->complex_value->values = NULL;

    if (nv == 0 && nc == 0) {
        return NGX_OK;
    }

    n = nv + 1;

    if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
                  + sizeof(ngx_http_script_var_code_t))
        + sizeof(uintptr_t);

    if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
        return NGX_ERROR;
    }

    n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
                   + sizeof(ngx_http_script_var_code_t))
                + sizeof(uintptr_t)
                + v->len
                + sizeof(uintptr_t) - 1)
            & ~(sizeof(uintptr_t) - 1);

    if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
        return NGX_ERROR;
    }

    pf = &flushes;
    pl = &lengths;
    pv = &values;

    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

    sc.cf = ccv->cf;
    sc.source = v;
    sc.flushes = &pf;
    sc.lengths = &pl;
    sc.values = &pv;
    sc.complete_lengths = 1;
    sc.complete_values = 1;
    sc.zero = ccv->zero;
    sc.conf_prefix = ccv->conf_prefix;
    sc.root_prefix = ccv->root_prefix;

    if (ngx_http_script_compile(&sc) != NGX_OK) {
        return NGX_ERROR;
    }

    if (flushes.nelts) {
        ccv->complex_value->flushes = flushes.elts;
        ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
    }

    ccv->complex_value->lengths = lengths.elts;
    ccv->complex_value->values = values.elts;

    return NGX_OK;
}

该函数用于将 Nginx 配置中的动态字符串(包含变量或特殊符号)编译为可运行时解析的内部结构 ,以支持后续高效地生成实际值 


    v = ccv->value;

    nv = 0;
    nc = 0;

    for (i = 0; i < v->len; i++) {
        if (v->data[i] == '$') {
            if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
                nc++;

            } else {
                nv++;
            }
        }
    }

v = ccv->value;

获取待编译的字符串值


nv = 0;

初始化变量计数器

nv(variable count):统计普通变量(如 $var)的数量


nc = 0;

初始化变量计数器

nc(capture count):统计正则捕获组变量(如 $1-9)的数量


for (i = 0; i < v->len; i++) { ... }

遍历字符串的每个字符,逐个分析是否为变量


if (v->data[i] == '$') { ... }

检测变量起始符 $

如果当前字符是 $,则进入变量分析逻辑

变量以 $ 开头,需进一步判断是普通变量还是正则捕获组


此次 没有符合条件的值

循环结束后

nv=0    nc=0

    if ((v->len == 0 || v->data[0] != '$')
        && (ccv->conf_prefix || ccv->root_prefix))
    {
        if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
            return NGX_ERROR;
        }

        ccv->conf_prefix = 0;
        ccv->root_prefix = 0;
    }

if ((v->len == 0 || v->data[0] != '$') && (ccv->conf_prefix || ccv->root_prefix))

  • v->len == 0 :检查字符串是否为空。
  • v->data[0] != '$' :检查字符串是否以 $ 开头(即是否为变量)
  • ccv->conf_prefix || ccv->root_prefix :检查是否需要添加前缀(配置路径或根路径)

当字符串是静态路径 (非变量、非空)且需要路径前缀时,进入处理逻辑


ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix)

将相对路径转换为绝对路径


此次

v->len =9
v->data[0]=/
ccv->conf_prefix=0
ccv->root_prefix=0

条件不成立

    ccv->complex_value->value = *v;
    ccv->complex_value->flushes = NULL;
    ccv->complex_value->lengths = NULL;
    ccv->complex_value->values = NULL;

 ccv->complex_value->value = *v;

保存原始字符串值

v 是经过路径处理后的字符串


ccv->complex_value->flushes = NULL;

初始化

需要清除缓存的变量索引列表


ccv->complex_value->lengths = NULL;

初始化 lengths 指针

lengths 存储计算动态值长度的指令数组


ccv->complex_value->values = NULL;

初始化 values 指针

values 存储生成动态值内容的指令数组


ngx_http_complex_value_t-CSDN博客

    if (nv == 0 && nc == 0) {
        return NGX_OK;
    }

 条件成立

返回 NGX_OK


http://www.kler.cn/a/610539.html

相关文章:

  • 文献学习:单细胞+临床+模型构建 | 一篇Molecular Cancer文献如何完整解读CDK4/6i耐药机制
  • SpringBoot大学生竞赛管理系统设计与实现
  • Redis 在后端系统中的高效应用
  • 去中心化金融
  • Maven插件学习(一)——生成可执行的 JAR 文件
  • AI时代智慧园区新标杆:华为联合51WORLD打造智能运营中心2.0
  • 六十天Linux从0到项目搭建(第五天)(file、bash 和 shell 的区别、目录权限、默认权限umask、粘滞位、使用系统自带的包管理工具)
  • 文件上传绕过的小点总结(4)
  • Spring Boot响应压缩配置与优化
  • qt QOffscreenSurface详解
  • Linux——进程信号(2)(函数信号与软件信号与硬件中断)
  • 问题:md文档转换word,html,图片,excel,csv
  • 《Git江湖录·分支篇》
  • 阿里巴巴1688类网站高保真原型设计
  • 文献分享: ColXTR——将ColBERTv2的优化引入ColXTR
  • Stable Diffusion 3.0 :一键开启你的AI绘画之旅
  • Rust从入门到精通之入门篇:6.函数
  • SpringBoot中安全的设置阿里云日志SLS的accessKey
  • 26考研——栈、队列和数组_栈(3)
  • 三维空间中点、线、面的关系