ngx_http_core_root

news2025/3/29 3:53:09

定义在 src\http\ngx_http_core_module.c 

static char *
ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_core_loc_conf_t *clcf = conf;

    ngx_str_t                  *value;
    ngx_int_t                   alias;
    ngx_uint_t                  n;
    ngx_http_script_compile_t   sc;

    alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;

    if (clcf->root.data) {

        if ((clcf->alias != 0) == alias) {
            return "is duplicate";
        }

        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "\"%V\" directive is duplicate, "
                           "\"%s\" directive was specified earlier",
                           &cmd->name, clcf->alias ? "alias" : "root");

        return NGX_CONF_ERROR;
    }

    if (clcf->named && alias) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the \"alias\" directive cannot be used "
                           "inside the named location");

        return NGX_CONF_ERROR;
    }

    value = cf->args->elts;

    if (ngx_strstr(value[1].data, "$document_root")
        || ngx_strstr(value[1].data, "${document_root}"))
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the $document_root variable cannot be used "
                           "in the \"%V\" directive",
                           &cmd->name);

        return NGX_CONF_ERROR;
    }

    if (ngx_strstr(value[1].data, "$realpath_root")
        || ngx_strstr(value[1].data, "${realpath_root}"))
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the $realpath_root variable cannot be used "
                           "in the \"%V\" directive",
                           &cmd->name);

        return NGX_CONF_ERROR;
    }

    clcf->alias = alias ? clcf->name.len : 0;
    clcf->root = value[1];

    if (!alias && clcf->root.len > 0
        && clcf->root.data[clcf->root.len - 1] == '/')
    {
        clcf->root.len--;
    }

    if (clcf->root.data[0] != '$') {
        if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
            return NGX_CONF_ERROR;
        }
    }

    n = ngx_http_script_variables_count(&clcf->root);

    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
    sc.variables = n;

#if (NGX_PCRE)
    if (alias && clcf->regex) {
        clcf->alias = NGX_MAX_SIZE_T_VALUE;
        n = 1;
    }
#endif

    if (n) {
        sc.cf = cf;
        sc.source = &clcf->root;
        sc.lengths = &clcf->root_lengths;
        sc.values = &clcf->root_values;
        sc.complete_lengths = 1;
        sc.complete_values = 1;

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

    return NGX_CONF_OK;
}

ngx_http_core_root 函数是 Nginx 中处理 rootalias 配置指令的核心逻辑实现


 

alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;

通过指令名称长度判断当前处理的是 root 还是 alias 指令

当前的指令是 root

所以 alias=0

    if (clcf->root.data) {

        if ((clcf->alias != 0) == alias) {
            return "is duplicate";
        }

        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "\"%V\" directive is duplicate, "
                           "\"%s\" directive was specified earlier",
                           &cmd->name, clcf->alias ? "alias" : "root");

        return NGX_CONF_ERROR;
    }

 逻辑 clcf->root.data 是存储路径值的指针。若非空,说明当前配置块(如 location)已设置过 rootalias

意义 :避免重复或冲突的路径配置。

同一指令重复 (如两次 root):直接返回 "is duplicate"

不同指令冲突 (如 root 后跟 alias):记录详细日志后终止

    if (clcf->named && alias) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the \"alias\" directive cannot be used "
                           "inside the named location");

        return NGX_CONF_ERROR;
    }

clcf->named:表示当前 location 是一个命名 location(如 location @name)。

alias:当前指令是 alias(值为 1)。

若两者同时为真,触发错误逻辑。

意义 :命名 location 的特殊用途与 alias 的路径替换逻辑存在冲突

此时 clcf->named=0    alias=0

条件不成立

    value = cf->args->elts;

    if (ngx_strstr(value[1].data, "$document_root")
        || ngx_strstr(value[1].data, "${document_root}"))
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the $document_root variable cannot be used "
                           "in the \"%V\" directive",
                           &cmd->name);

        return NGX_CONF_ERROR;
    }

 禁止在 rootalias 指令中直接使用 $document_root${document_root} 变量

  • 逻辑 :通过 ngx_strstr 函数检查路径参数(value[1])中是否包含变量 $document_root${document_root}
  • 意义 :直接使用这些变量会导致循环依赖 ,因为 $document_root 的值正是由 root/alias 指令定义的。

此时

value[1].data=html

条件不成立

 

    if (ngx_strstr(value[1].data, "$realpath_root")
        || ngx_strstr(value[1].data, "${realpath_root}"))
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "the $realpath_root variable cannot be used "
                           "in the \"%V\" directive",
                           &cmd->name);

        return NGX_CONF_ERROR;
    }

禁止在 rootalias 指令中直接使用 $realpath_root${realpath_root} 变量

此时条件不成立

    clcf->alias = alias ? clcf->name.len : 0;
    clcf->root = value[1];
clcf->alias = alias ? clcf->name.len : 0;
  • 作用
    设置 clcf->alias 的值,用于标识当前配置是 alias 还是 root,并记录 alias 的替换长度。

  • 逻辑

    • alias 是一个布尔变量:

      • 1 表示当前处理的是 alias 指令。
      • 0 表示当前处理的是 root 指令。
    • 若为 alias
      clcf->alias 被赋值为 clcf->name.len(即当前 location 名称的长度)。

若为 root
clcf->alias 被置为 0

clcf->root = value[1];
  • 作用
    将用户配置的路径值保存到 clcf->root 中。

  • 逻辑

    • value[1] 是指令的参数列表中的第二个元素(索引从 0 开始)

此时 

clcf->alias=0
clcf->root=html

    if (!alias && clcf->root.len > 0
        && clcf->root.data[clcf->root.len - 1] == '/')
    {
        clcf->root.len--;
    }

!alias:仅对 root 指令生效(alias0 时为 root)。

clcf->root.len > 0:确保路径非空,避免无效操作。

clcf->root.data[clcf->root.len - 1] == '/':检查路径末尾是否为斜杠 /

若当前是 root 指令,且路径非空且以 / 结尾,则进入处理逻辑

将路径的长度减 1隐式删除末尾的斜杠

避免拼接 URI 时可能出现双斜杠

此时条件不成立

 

    if (clcf->root.data[0] != '$') {
        if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
            return NGX_CONF_ERROR;
        }
    }

    clcf->root.data[0] 是路径的第一个字符。

    若不以 $ 开头,表示路径是静态字符串 ,而非变量(如 $document_root)。

    意义
    仅对静态路径进行规范化处理,变量路径需在运行时动态解析。

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

    参数 cf->cycle:Nginx 全局配置上下文。

    参数 &clcf->root:待处理的路径。

    参数 0:标志位(此处未启用特殊选项,如符号链接解析)。

    示例
    若 Nginx 前缀为 /usr/local/nginx,用户配置 root html;,则转换后路径为 /usr/local/nginx/html

    此时 root.data=/usr/local/nginx/html

    n = ngx_http_script_variables_count(&clcf->root);

     ngx_http_script_variables_count 遍历路径字符串(clcf->root),统计符合变量格式($var${var})的出现次数。

    示例
    路径 "/var/www/$host/$uri" 包含 2 个变量 $host$uri),因此 n = 2

    设计目的

    动态路径预处理
    n > 0,表示路径需要运行时动态解析变量,后续需通过脚本引擎(ngx_http_script)生成解析逻辑。
    n = 0,路径为静态字符串,直接使用即可。

    ngx_http_script_variables_count-CSDN博客

    此时 n = 0

     

        ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
        sc.variables = n;
    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
    • 作用
      初始化 ngx_http_script_compile_t 结构体变量 sc,将其所有字段置零

    sc.variables = n;
    • 作用
      设置脚本编译器的变量数量 ,即路径中需要动态解析的变量个数。

    ngx_http_script_compile_t-CSDN博客

    #if (NGX_PCRE)
        if (alias && clcf->regex) {
            clcf->alias = NGX_MAX_SIZE_T_VALUE;
            n = 1;
        }
    #endif

     if (alias && clcf->regex)

    当前处理的是 alias

    当前使用了正则表达式匹配

    此时 

    alias=0
    clcf->regex=NULL

    条件不成立

        if (n) {
            sc.cf = cf;
            sc.source = &clcf->root;
            sc.lengths = &clcf->root_lengths;
            sc.values = &clcf->root_values;
            sc.complete_lengths = 1;
            sc.complete_values = 1;
    
            if (ngx_http_script_compile(&sc) != NGX_OK) {
                return NGX_CONF_ERROR;
            }
        }
    if (n) {
    • 作用
      检查路径中是否包含变量(n > 0)。若存在变量,进入动态路径编译流程

    条件不成立

        return NGX_CONF_OK;

    返回 NGX_CONF_OK;


    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2322152.html

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

    相关文章

    光谱范围与颜色感知的关系

    光谱范围与颜色感知是光学、生理学及技术应用交叉的核心课题,两者通过波长分布、人眼响应及技术处理共同决定人类对色彩的认知。以下是其关系的系统解析: ‌1.基础原理:光谱范围与可见光‌ ‌光谱范围定义‌: 电磁波谱中能被特定…

    网络地址转换技术(2)

    NAT的配置方法: (一)静态NAT的配置方法 进入接口视图配置NAT转换规则 Nat static global 公网地址 inside 私网地址 内网终端PC2(192.168.20.2/24)与公网路由器AR1的G0/0/1(11.22.33.1/24)做…

    Python正则表达式(一)

    目录 一、正则表达式的基本概念 1、基本概念 2、正则表达式的特殊字符 二、范围符号和量词 1、范围符号 2、匹配汉字 3、量词 三、正则表达式函数 1、使用正则表达式: 2、re.match()函数 3、re.search()函数 4、findall()函数 5、re.finditer()函数 6…

    【TI MSPM0】PWM学习

    一、样例展示 #include "ti_msp_dl_config.h"int main(void) {SYSCFG_DL_init();DL_TimerG_startCounter(PWM_0_INST);while (1) {__WFI();} } TimerG0输出一对边缘对齐的PWM信号 TimerG0会输出一对62.5Hz的边缘对齐的PWM信号在PA12和PA13引脚上,PA12被…

    MySQL: 创建两个关联的表,用联表sql创建一个新表

    MySQL: 创建两个关联的表 建表思路 USERS 表:包含用户的基本信息,像 ID、NAME、EMAIL 等。v_card 表:存有虚拟卡的相关信息,如 type 和 amount。关联字段:USERS 表的 V_CARD 字段和 v_card 表的 v_card 字段用于建立…

    更改 vscode ! + table 默认生成的 html 初始化模板

    vscode ! 快速成的 html 代码默认为&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>D…

    使用LVS的 NAT 模式实现 3 台RS的轮询访问

    节点规划 1、配置RS RS的网络配置为NAT模式&#xff0c;三台RS的网关配置为192.168.10.8 1.1配置RS1 1.1.1修改主机名和IP地址 [rootlocalhost ~]# hostnamectl hostname rs1 [rootlocalhost ~]# nmcli c modify ens160 ipv4.method manual ipv4.addresses 192.168.10.7/24…

    MySQL实战(尚硅谷)

    要求 代码 # 准备数据 CREATE DATABASE IF NOT EXISTS company;USE company;CREATE TABLE IF NOT EXISTS employees(employee_id INT PRIMARY KEY,first_name VARCHAR(50),last_name VARCHAR(50),department_id INT );DESC employees;CREATE TABLE IF NOT EXISTS departments…

    华为p10 plus 鸿蒙2.0降级emui9.1.0.228

    需要用到的工具 HiSuite Proxy V3 华为手机助手11.0.0.530_ove或者11.0.0.630_ove应该都可以。 官方的通道已关闭&#xff0c;所以要用代理&#xff0c;127.0.0.1端口7777 https://www.firmfinder.ml/ https://professorjtj.github.io/v2/ https://hisubway.online/articl…

    C# Modbus RTU学习记录

    继C# Modbus TCP/IP学习记录后&#xff0c;尝试串口通信。 操作步骤&#xff1a; 1.使用Visual Studio安装Nuget包NModbus.Serial。 2.使用Modbus Slave应用程序&#xff0c;工具栏Connection项&#xff0c;单击Connect&#xff0c;弹窗Connection Setup&#xff0c;修改Con…

    AI+Xmind自动生成测试用例(思维导图格式)

    一、操作步骤: 步骤1:创建自动生成测试用例智能体 方式:使用通义千问/豆包智能体生成,以下两个是我已经训练好的智能体,直接打开使用即可 通义智能体: https://lxblog.com/qianwen/share?shareId=b0cd664d-5001-42f0-b494-adc98934aba5&type=agentCard 豆包智能…

    (二)手眼标定——概述+原理+常用方法汇总+代码实战(C++)

    一、手眼标定简述 手眼标定的目的&#xff1a;让机械臂和相机关联&#xff0c;相机充当机械臂的”眼睛“&#xff0c;最终实现指哪打哪 相机的使用前提首先需要进行相机标定&#xff0c;可以参考博文&#xff1a;&#xff08;一&#xff09;相机标定——四大坐标系的介绍、对…

    【Linux网络-NAT、代理服务、内网穿透】

    一、NAT技术 1.NAT技术背景 之前我们讨论了&#xff0c;IPV4协议中&#xff0c;IP地址数量不充足的问题 NAT技术当前解决IP地址不够用的主要手段&#xff0c;是路由器的一个重要功能 NAT&#xff08;网络地址转换&#xff0c;Network Address Translation&#xff09;是一种…

    新手村:逻辑回归-理解02:逻辑回归中的伯努利分布

    新手村&#xff1a;逻辑回归-理解02&#xff1a;逻辑回归中的伯努利分布 伯努利分布在逻辑回归中的潜在含义及其与后续推导的因果关系 1. 伯努利分布作为逻辑回归的理论基础 ⭐️ 逻辑回归的核心目标是: 建模二分类问题中 目标变量 y y y 的概率分布。 伯努利分布&#xff08…

    golang Error的一些坑

    golang Error的一些坑 golang error的设计可能是被人吐槽最多的golang设计了。 最经典的err!nil只影响代码风格设计&#xff0c;而有一些坑会导致我们的程序发生一些与我们预期不符的问题&#xff0c;开发过程中需要注意。 ​​ errors.Is​判断error是否Wrap不符合预期 ​…

    【STM32】知识点介绍二:GPIO引脚介绍

    文章目录 一、概述二、GPIO的工作模式三、寄存器编程 一、概述 GPIO&#xff08;英语&#xff1a;General-purpose input/output&#xff09;,即通用I/O(输入/输出)端口&#xff0c;是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来&#xff0c;可实现与外部通讯、…

    【AI】NLP

    不定期更新&#xff0c;建议关注收藏点赞。 目录 transformer大语言模型Google Gemma疫情网民情绪识别 整体框架 baseline构建 模型调参、模型优化、其他模型 数据trick、指标优化、magic feature 数据增强、伪标签、迁移学习 模型融合sklearn中TFIDF参数详解 频率阈值可以去掉…

    Go 代理爬虫

    现在注册&#xff0c;还送15美金注册奖励金 --- 亮数据-网络IP代理及全网数据一站式服务商 使用代理服务器&#xff0c;通过 Colly、Goquery、Selenium 进行网络爬虫的基础示例程序 本仓库包含两个分支&#xff1a; basic 分支包含供 Go Proxy Servers 这篇文章改动的基础代码…

    【NLP 43、大模型技术发展】

    目录 一、ELMo 2018 训练目标 二、GPT-1 2018 训练目标 三、BERT 2018 训练目标 四、Ernie —— baidu 2019 五、Ernie —— Tsinghua 2019 六、GPT-2 2019 七、UNILM 2019 八、Transformer - XL & XLNet 2019 1.模型结构 Ⅰ、循环机制 Recurrence Mechanism Ⅱ、相对位置…

    在普通用户下修改root用户密码

    1 从普通用户切换到root用户 sudo -s 再输入密码。 2 输入passwd ,会提醒你输入当前用户密码&#xff0c;验证后会提醒你输入root用户密码。 3 切换到root用户&#xff0c;使用修改过的密码登陆。 4 成功进入root用户。