ngx_conf_handler

定义在 src\core\ngx_conf_file.c

static ngx_int_t
ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{char           *rv;void           *conf, **confp;ngx_uint_t      i, found;ngx_str_t      *name;ngx_command_t  *cmd;name = cf->args->elts;found = 0;for (i = 0; cf->cycle->modules[i]; i++) {cmd = cf->cycle->modules[i]->commands;if (cmd == NULL) {continue;}for ( /* void */ ; cmd->name.len; cmd++) {if (name->len != cmd->name.len) {continue;}if (ngx_strcmp(name->data, cmd->name.data) != 0) {continue;}found = 1;if (cf->cycle->modules[i]->type != NGX_CONF_MODULE&& cf->cycle->modules[i]->type != cf->module_type){continue;}/* is the directive's location right ? */if (!(cmd->type & cf->cmd_type)) {continue;}if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" is not terminated by \";\"",name->data);return NGX_ERROR;}if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" has no opening \"{\"",name->data);return NGX_ERROR;}/* is the directive's argument count right ? */if (!(cmd->type & NGX_CONF_ANY)) {if (cmd->type & NGX_CONF_FLAG) {if (cf->args->nelts != 2) {goto invalid;}} else if (cmd->type & NGX_CONF_1MORE) {if (cf->args->nelts < 2) {goto invalid;}} else if (cmd->type & NGX_CONF_2MORE) {if (cf->args->nelts < 3) {goto invalid;}} else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {goto invalid;} else if (!(cmd->type & argument_number[cf->args->nelts - 1])){goto invalid;}}/* set up the directive's configuration context */conf = NULL;if (cmd->type & NGX_DIRECT_CONF) {conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];} else if (cmd->type & NGX_MAIN_CONF) {conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]);} else if (cf->ctx) {confp = *(void **) ((char *) cf->ctx + cmd->conf);if (confp) {conf = confp[cf->cycle->modules[i]->ctx_index];}}rv = cmd->set(cf, cmd, conf);if (rv == NGX_CONF_OK) {return NGX_OK;}if (rv == NGX_CONF_ERROR) {return NGX_ERROR;}ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"\"%s\" directive %s", name->data, rv);return NGX_ERROR;}}if (found) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"\"%s\" directive is not allowed here", name->data);return NGX_ERROR;}ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"unknown directive \"%s\"", name->data);return NGX_ERROR;invalid:ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"invalid number of arguments in \"%s\" directive",name->data);return NGX_ERROR;
}

ngx_conf_handler 是 Nginx 配置解析的核心函数,其主要作用是根据当前解析到的配置指令,找到对应的模块命令并执行相关校验和设置


    name = cf->args->elts;found = 0;

 name = cf->args->elts;
将当前配置指令的参数列表(数组)的起始地址赋值给 name 指针,以便后续遍历和匹配指令名。

found = 0;
初始化标志变量 found 为 0,表示尚未找到与当前配置指令匹配的模块命令。

found 是一个布尔标记,用于记录是否在模块的指令列表中成功匹配到当前指令名。
初始值为 0(未找到),在后续遍历模块的 commands 数组时,若匹配到指令名,则置为 1


此时

name->data=worker_processes


worker_processes 用于定义 Nginx 工作进程(Worker Processes)的数量

  • 每个 worker_process 是一个独立的进程,负责处理客户端请求。
  • 多进程设计 :通过启用多个工作进程,Nginx 可以充分利用多核 CPU 的性能,实现高并发处理。
  • 默认值 1(但通常建议根据服务器 CPU 核心数调整)。

    for (i = 0; cf->cycle->modules[i]; i++) {cmd = cf->cycle->modules[i]->commands;if (cmd == NULL) {continue;}

 遍历 Nginx 所有已加载的模块,检查每个模块是否包含需要处理的配置指令。

获取模块的指令列表:cmd = cf->cycle->modules[i]->commands;
获取当前模块支持的配置指令列表(commands 数组),用于后续匹配当前解析的指令。

commands 是 ngx_module_t 结构体的成员,指向一个 ngx_command_t 数组,表示该模块支持的配置指令。

cmd 是 ngx_command_t* 类型指针,指向当前模块的指令列表。
后续内层循环会遍历 cmd 数组,匹配当前配置指令名。

跳过无指令的模块:if (cmd == NULL) { continue; }
如果当前模块没有定义任何配置指令(commands 为 NULL),则跳过该模块,继续检查下一个模块。
某些模块可能不处理配置指令(例如仅提供功能的模块),其 commands 字段会被设为 NULL。

意图
遍历所有模块
通过外层循环,确保每个模块都有机会检查是否支持当前解析的配置指令。

筛选有效模块
仅处理包含配置指令(commands 非空)的模块,忽略无指令的模块。

为内层循环做准备
每个模块的 commands 数组将在内层循环中被遍历,逐个匹配指令名


for ( /* void */ ; cmd->name.len; cmd++) {

 遍历当前模块的指令列表(commands 数组),逐个匹配当前解析的配置指令名。


cmd->name.len 为 0 时,表示已遍历到指令列表的末尾(每个模块的 commands 数组以 cmd->name.len = 0 的哨兵元素结束)。


 

            if (name->len != cmd->name.len) {continue;}

如果长度不同,说明指令名一定不匹配,直接跳过当前 cmd


            if (ngx_strcmp(name->data, cmd->name.data) != 0) {continue;}

 

比较当前配置指令名与模块定义的指令名是否完全一致。

  • 返回值为 0 表示字符串内容完全相同,说明找到匹配的指令。

  • 若名称不匹配,跳过当前指令,继续检查下一个 cmd


ngx_strcmp

ngx_strcmp-CSDN博客


found = 1;

 找到了 匹配的指令


此时

cf->cycle->modules[0]->name=ngx_core_module


 

            if (cf->cycle->modules[i]->type != NGX_CONF_MODULE&& cf->cycle->modules[i]->type != cf->module_type){continue;}

如果当前模块类型 既不是通用配置模块也不匹配当前配置阶段的模块类型cf->module_type),则跳过该指令


 此时

cf->cycle->modules[0]->type=0x45524F43
cf->module_type=0x45524F43
NGX_CONF_MODULE=0x464E4F43


0x45524F43 是 NGX_CORE_MODULE

./nginx-1.24.0/src/core/ngx_conf_file.h:70:#define NGX_CORE_MODULE      0x45524F43  /* "CORE" */

条件不成立


            /* is the directive's location right ? */if (!(cmd->type & cf->cmd_type)) {continue;}

验证 配置指令出现的位置


cmd->type 表示该指令预期可以出现的位置

cf->cmd_type 表示当前配置文件中的位置


此时

cmd->type     =0x1010002
cf->cmd_type=0x1000000 (NGX_MAIN_CONF)

./nginx-1.24.0/src/core/ngx_conf_file.h:51:#define NGX_MAIN_CONF        0x01000000


 

            if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" is not terminated by \";\"",name->data);return NGX_ERROR;}
检查非块指令是否以分号结尾
  • cmd->type & NGX_CONF_BLOCK
    NGX_CONF_BLOCK 是块指令标志,若未设置,说明当前指令是非块指令
  • last != NGX_OK
    last 参数表示解析器的状态:
    • NGX_OK:正常结束(指令以分号 ; 结尾)。

#define NGX_CONF_BLOCK       0x00000100

此时

last=0 (NGX_OK



            if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" has no opening \"{\"",name->data);return NGX_ERROR;}

 若指令是块类型,但未以 { 开始(last 非 NGX_CONF_BLOCK_START),则触发错误:


#define NGX_CONF_BLOCK_START 1

 

当前指令不是块类型


 

            /* is the directive's argument count right ? */if (!(cmd->type & NGX_CONF_ANY)) {

检查指令的参数数量


NGX_CONF_ANY 表示指令允许任意数量参数

不是 允许任意数量参数 

进入进一步的检查


此时条件成立

cf->args->nelts=2


                if (cmd->type & NGX_CONF_FLAG) {if (cf->args->nelts != 2) {goto invalid;}}

 

  • NGX_CONF_FLAG 表示指令需要一个布尔值参数。
  • 布尔指令的完整格式为 指令名 参数,参数数量必须为 2(例如 rewrite_log on;)

此时条件不成立


            else if (cmd->type & NGX_CONF_1MORE) {if (cf->args->nelts < 2) {goto invalid;}} 

NGX_CONF_1MORE 表示指令需要至少 1 个参数


此时条件不成立


                } else if (cmd->type & NGX_CONF_2MORE) {if (cf->args->nelts < 3) {goto invalid;}}

NGX_CONF_2MORE 表示指令需要至少 2 个参数


此时条件不成立


                } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {goto invalid;}

检查参数总数是否超过允许的最大值


此时条件不成立


                } else if (!(cmd->type & argument_number[cf->args->nelts - 1])){goto invalid;}

 精确匹配参数数量(当前指令的参数数量是固定的而不是 至少一个这种不固定的)

argument_number 是一个预定义的数组,将参数数量映射到对应的标志位。例如

static ngx_uint_t argument_number[] = {NGX_CONF_NOARGS,  // 0 参数(仅指令名)NGX_CONF_TAKE1,   // 1 参数NGX_CONF_TAKE2,   // 2 参数// ... 其他
};

cf->args->nelts - 1 将参数总数转换为实际参数数量(减去指令名)


此时条件不成立

通过了参数数量的校验


 

            /* set up the directive's configuration context */conf = NULL;if (cmd->type & NGX_DIRECT_CONF) {conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];

为指令(cmd)设置配置上下文(conf),并调用指令的 set 方法将配置值写入上下文。
根据指令类型选择不同的配置存储位置,最终处理 set 方法的返回值。


NGX_DIRECT_CONF 是一种指令类型,用于定义必须直接出现在配置文件顶层(全局作用域)的指令,而不是嵌套在 httpserverlocation 等子配置块中 


NGX_DIRECT_CONF 指令的配置结构指针直接存储在模块的配置数组中


此时 条件成立

cf->cycle->modules[0]->index=0


rv = cmd->set(cf, cmd, conf);

 调用指令的 set 方法,解析指令,然后设置其所在配置结构的对应字段


当前指令是 worker_processes

worker_processes 指令的 set 函数

worker_processes 指令的 set 函数-CSDN博客


            if (rv == NGX_CONF_OK) {return NGX_OK;}

 返回 NGX_OK ,代表 指令处理成功

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

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

相关文章

Ubuntu系统美化

Ubuntu系统美化 一、Grub设置 1. 安装Grub Customizer【推荐】 Grub Customizer是一个用于自定义 GRUB 引导菜单的实用程序 sudo add-apt-repository ppa:danielrichter2007/grub-customizer && sudo apt update && sudo apt install -y grub-customizer2.…

零基础HTML·笔记(持续更新…)

基础认知 HTML标签的结构 <strong>文字变粗</strong> &#xff1c;开始标签&#xff1e;内容&#xff1c;结束标签&#xff1e; 结构说明&#xff1a; 标签由<、>、1、英文单词或字母组成。并且把标签中<>包括起来的英文单词或字母称为标签名。常…

nmcli创建wpa-psk2 wifi热点

1. 创建新的WiFi连接&#xff1a; sudo nmcli connection add type wifi ifname wlan0 con-name WiFi名称 autoconnect yes ssid WiFi名称 2. 配置接入点模式和IP共享&#xff1a; sudo nmcli connection modify WiFi名称 802-11-wireless.mode ap 802-11-wireless.band …

【消息队列kafka_中间件】一、快速入门分布式消息队列

在当今大数据和分布式系统盛行的时代&#xff0c;消息队列作为一种关键的中间件技术&#xff0c;发挥着举足轻重的作用。其中&#xff0c;Apache Kafka 以其卓越的性能、高可扩展性和强大的功能&#xff0c;成为众多企业构建分布式应用的首选消息队列解决方案。本篇文章将带你深…

在线地图支持天地图和腾讯地图,仪表板和数据大屏支持发布功能,DataEase开源BI工具v2.10.7 LTS版本发布

2025年4月11日&#xff0c;人人可用的开源BI工具DataEase正式发布v2.10.7 LTS版本。 这一版本的功能变动包括&#xff1a;数据源方面&#xff0c;Oracle数据源支持获取和查询物化视图&#xff1b;图表方面&#xff0c;在线地图支持天地图、腾讯地图&#xff1b;新增子弹图&…

【Linux实践系列】:匿名管道收尾+完善shell外壳程序

&#x1f525; 本文专栏&#xff1a;Linux Linux实践项目 &#x1f338;作者主页&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客励志语录&#xff1a; 人生总会有自己能力所不及的范围&#xff0c;但是如果你在你能力所及的范围尽了全部的努力&#xff0c;那你还有什么遗…

【C++初学】课后作业汇总复习(七) 指针-深浅copy

1、 HugeInt类:构造、、cout Description: 32位整数的计算机可以表示整数的范围近似为&#xff0d;20亿到&#xff0b;20亿。在这个范围内操作一般不会出现问题&#xff0c;但是有的应用程序可能需要使用超出上述范围的整数。C可以满足这个需求&#xff0c;创建功能强大的新的…

【C++】 —— 笔试刷题day_16

刷题_day16&#xff0c;继续加油啊 一、字符串替换 题目解析 这道题是一道简单的字符题目&#xff0c;题目给我们一个字符串A&#xff0c;和n表示A字符串的长度&#xff0c;再给出一个字符数组arg&#xff0c;m表示arg中是数据个数。 然我们在字符串A中找到%s然后替换成arg中的…

n8n 本地部署及实践应用,实现零成本自动化运营 Telegram 频道(保证好使)

n8n 本地部署及实践应用&#xff0c;实现零成本自动化运营 Telegram 频道&#xff08;保证好使&#xff09; 简介 n8n 介绍 一、高度可定制性 二、丰富的连接器生态 三、自托管部署&#xff08;本地部署&#xff09; 四、社区驱动 n8n 的部署 一、前期准备 二、部署步…

flutter 桌面应用之系统托盘

系统托盘(Tray) 系统托盘就是状态栏里面对应的图标点击菜单 主要有两款框架 框架一句话评价tray_manager轻量、简单、易用&#xff0c;适合常规托盘功能system_tray更底层、更强大、支持图标/菜单/消息弹窗等更多功能&#xff0c;但复杂度更高 &#x1f9f1; 基础能力对比 …

修改idea/android studio等编辑器快捷注释从当前行开头的反人类行为

不知道什么时候开始&#xff0c;idea编辑的快捷注释开始从当前行开头出现了&#xff0c;显得实在是难受&#xff0c;我只想让在当前行代码的部份开始缩进两个字符开始&#xff0c;这样才会显得更舒服。不知道有没有强迫症的猴子和我一样&#xff0c;就像下面的效果&#xff1a;…

MySQL慢查询全攻略:定位、分析与优化实战

&#x1f680; MySQL慢查询全攻略&#xff1a;定位、分析与优化实战 #数据库优化 #性能调优 #SQL优化 #MySQL实战 一、慢查询定位&#xff1a;找到性能瓶颈 1.1 开启慢查询日志 -- 查看当前配置 SHOW VARIABLES LIKE %slow_query%; -- 动态开启&#xff08;重启失效&…

当原型图与文字说明完全不同时,测试要怎么做?

当测试遇上左右手互搏的需求&#xff0c;怎么办&#xff1f; "这个弹窗样式怎么和文档写的不一样&#xff1f;"、"按钮位置怎么跑到左边去了&#xff1f;"——根据Deloitte的调查&#xff0c;62%的项目存在原型图与需求文档不一致的情况。这种"精神分…

关于量化交易在拉盘砸盘方面应用的部分思考

关于“砸盘”的深层解析与操盘逻辑 ​​一、砸盘的本质与市场含义​​ ​​砸盘​​指通过集中抛售大量筹码导致价格快速下跌的行为&#xff0c;其核心目标是​​制造恐慌、清洗浮筹或实现利益再分配​​。不同场景下的砸盘含义不同&#xff1a; ​​主动砸盘&#xff08;操控…

【项目管理】第12章 项目质量管理-- 知识点整理

项目管理-相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 项目管理知识域 知识点: (项目管理概论、立项管理、十大知识域、配置与变更管理、绩效域) 对应:第6章-第19章 第6章 项目管理概论 4分第13章 项目资源管理 3-4分第7章 项目…

一个好看的图集展示html页面源码

源码介绍 一个好看的图集展示html页面源码&#xff0c;适合展示自己的作品&#xff0c;页面美观大气&#xff0c;也可以作为产品展示或者个人引导页等等 源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c; 双击html文件可以本地运行…

2021第十二届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

记录刷题的过程、感悟、题解。 希望能帮到&#xff0c;那些与我一同前行的&#xff0c;来自远方的朋友&#x1f609; 大纲&#xff1a; 1、空间-&#xff08;题解&#xff09;-字节单位转换 2、卡片-&#xff08;题解&#xff09;-可以不用当组合来写&#xff0c;思维题 3、直…

LabVIEW 中 JSON 数据与簇的转换

在 LabVIEW 编程中&#xff0c;数据格式的处理与转换是极为关键的环节。其中&#xff0c;将数据在 JSON 格式与 LabVIEW 的簇结构之间进行转换是一项常见且重要的操作。这里展示的程序片段就涉及到这一关键功能&#xff0c;以下将详细介绍。 一、JSON 数据与簇的转换功能 &am…

蓝桥杯大模板

init.c void System_Init() {P0 0x00; //关闭蜂鸣器和继电器P2 P2 & 0x1f | 0xa0;P2 & 0x1f;P0 0x00; //关闭LEDP2 P2 & 0x1f | 0x80;P2 & 0x1f; } led.c #include <LED.H>idata unsigned char temp_1 0x00; idata unsigned char temp_old…

通过HTTP协议实现Git免密操作的解决方案

工作中会遇到这样的问题的。 通过HTTP协议实现Git免密操作的解决方案 方法一&#xff1a;启用全局凭据存储&#xff08;推荐&#xff09; 配置凭证存储‌ 执行以下命令&#xff0c;让Git永久保存账号密码&#xff08;首次操作后生效&#xff09;&#xff1a; git config --g…