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

ngx_http_merge_servers

1 定义

staticchar*ngx_http_merge_servers(ngx_conf_t*cf,ngx_http_core_main_conf_t*cmcf,ngx_http_module_t*module,ngx_uint_tctx_index){char*rv;ngx_uint_ts;ngx_http_conf_ctx_t*ctx,saved;ngx_http_core_loc_conf_t*clcf;ngx_http_core_srv_conf_t**cscfp;cscfp=cmcf->servers.elts;ctx=(ngx_http_conf_ctx_t*)cf->ctx;saved=*ctx;rv=NGX_CONF_OK;for(s=0;s<cmcf->servers.nelts;s++){/* merge the server{}s' srv_conf's */ctx->srv_conf=cscfp[s]->ctx->srv_conf;if(module->merge_srv_conf){rv=module->merge_srv_conf(cf,saved.srv_conf[ctx_index],cscfp[s]->ctx->srv_conf[ctx_index]);if(rv!=NGX_CONF_OK){gotofailed;}}if(module->merge_loc_conf){/* merge the server{}'s loc_conf */ctx->loc_conf=cscfp[s]->ctx->loc_conf;rv=module->merge_loc_conf(cf,saved.loc_conf[ctx_index],cscfp[s]->ctx->loc_conf[ctx_index]);if(rv!=NGX_CONF_OK){gotofailed;}/* merge the locations{}' loc_conf's */clcf=cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];rv=ngx_http_merge_locations(cf,clcf->locations,cscfp[s]->ctx->loc_conf,module,ctx_index);if(rv!=NGX_CONF_OK){gotofailed;}}}failed:*ctx=saved;returnrv;}
`ngx_http_merge_servers` 函数用于 将指定 HTTP 模块的配置从主配置(`main`)合并到各个 `server` 块以及它们内部的 `location` 块中。

2 详解

1 函数签名

staticchar*ngx_http_merge_servers(ngx_conf_t*cf,ngx_http_core_main_conf_t*cmcf,ngx_http_module_t*module,ngx_uint_tctx_index)
返回值 返回一个指向字符串的指针。 成功时返回 NGX_CONF_OK,该宏被定义为 (char *) NULL。 如果合并过程中发生错误,则返回一个指向错误信息字符串的指针
参数 ngx_conf_t *cf 当前配置解析上下文 ngx_http_core_main_conf_t *cmcf 指向 HTTP 核心模块的主配置结构体 ngx_http_module_t *module 指向 http 模块的定义 ngx_uint_t ctx_index 当前模块的配置结构体在 srv_conf 和 loc_conf 数组中的位置索引

2 逻辑流程

1 局部变量 2 变量初始化 3 遍历每个 server {} 块 3-1 切换 Server 配置上下文 3-2 检查并调用 Server 合并回调 3-3 检查并准备合并 Location 配置 3-4 递归合并该 server 内部的所有 location 块 4 错误处理 5 返回处理结果

1 局部变量
{char*rv;ngx_uint_ts;ngx_http_conf_ctx_t*ctx,saved;ngx_http_core_loc_conf_t*clcf;ngx_http_core_srv_conf_t**cscfp;

2 变量初始化
cscfp=cmcf->servers.elts;ctx=(ngx_http_conf_ctx_t*)cf->ctx;saved=*ctx;rv=NGX_CONF_OK;
#1 获取 cmcf(HTTP 核心主配置)中 servers 数组的元素指针,并赋值给 cscfp。 cmcf 是 ngx_http_core_main_conf_t 结构体,代表 http {} 块的核心配置。 cmcf->servers 是一个 ngx_array_t 类型的动态数组, 里面存储了所有解析出来的 server {} 块的配置上下文指针。 .elts 是 Nginx 数组结构体中指向实际数据内存块的指针。 cscfp 的类型是 ngx_http_core_srv_conf_t **,即“服务器核心配置指针的数组”。 意义: 获取遍历入口。 Nginx 支持配置多个虚拟主机(多个 server {}), 这行代码拿到了所有虚拟主机配置列表的起始地址, 使得后续的 for 循环可以通过下标 s 访问每一个 server {} 的配置。
#2 cf: 当前配置上下文,类型为 ngx_conf_t *,包含解析器状态、内存池、当前指令参数等。 cf->ctx: void * 类型,指向当前配置层级的上下文。 在 HTTP 模块中,该上下文实际是 ngx_http_conf_ctx_t 结构体。 ngx_http_conf_ctx_t: 包含了三个指针数组 main_conf、srv_conf、loc_conf, 分别存储各模块在 main、server、location 级别的配置。 强制类型转换:将 cf->ctx 转换为 ngx_http_conf_ctx_t * 并赋值给 ctx。 意义: 将当前解析器上下文的通用指针转换为 HTTP 模块可用的具体结构体指针,以便访问各模块的配置数组。
#3 saved 在函数开头声明为 ngx_http_conf_ctx_t saved;(结构体变量,非指针)。 操作:将 ctx 指向的整个 ngx_http_conf_ctx_t 结构体的内容拷贝到 saved 中。 意义: 保存原始上下文。 在后续遍历每个 server 时,会临时修改 ctx 所指向的结构体, 通过保存副本,可以在函数结束或出错时恢复上下文,避免影响其他模块或其他操作。
#4 rv 是函数的返回值, 类型 char * NGX_CONF_OK 宏定义为 (char *) NULL,表示成功。 意义:初始化返回值为成功状态。 后续如果任何合并操作失败,会将 rv 设置为具体的错误字符串(非空), 并跳转到错误处理。最后返回 rv 供上层判断。

3 遍历每个 server {} 块
for(s=0;s<cmcf->servers.nelts;s++){/* merge the server{}s' srv_conf's */

3-1 切换 Server 配置上下文
ctx->srv_conf=cscfp[s]->ctx->srv_conf;
修改全局上下文 ctx 中的 srv_conf 指针,使其指向当前循环到的第 s 个 server {} 块的 srv_conf 配置数组。 cscfp[s] 是第 s 个 server 的核心配置(ngx_http_core_srv_conf_t *) cscfp[s]->ctx 是该 server 自己的上下文(ngx_http_conf_ctx_t *), 其中包含了该 server 的 srv_conf 和 loc_conf 数组。 通过赋值,使得后续通过 ctx->srv_conf 访问到的配置就是当前 server 的配置

3-2 检查并调用 Server 合并回调
if(module->merge_srv_conf){rv=module->merge_srv_conf(cf,saved.srv_conf[ctx_index],cscfp[s]->ctx->srv_conf[ctx_index]);if(rv!=NGX_CONF_OK){gotofailed;}}
#1 检查当前模块是否提供了 merge_srv_conf 回调函数。 如果该函数指针非空,则说明模块需要合并 server 级配置,执行合并;否则跳过。
#2 调用模块的 merge_srv_conf 函数,将主配置(父级)与当前 server 的配置(子级)合并。 参数: cf:配置上下文。 saved.srv_conf[ctx_index]: 父级配置,即主层级(http 块)的默认配置。 cscfp[s]->ctx->srv_conf[ctx_index]: 子级配置,即当前 server 的配置(可能覆盖父级)。 意义:完成 server 级配置的继承与合并,结果将用于该 server 的最终配置。
#3 如果合并过程中出现错误,立即进入错误处理流程。

3-3 检查并准备合并 Location 配置
if(module->merge_loc_conf){/* merge the server{}'s loc_conf */ctx->loc_conf=cscfp[s]->ctx->loc_conf;rv=module->merge_loc_conf(cf,saved.loc_conf[ctx_index],cscfp[s]->ctx->loc_conf[ctx_index]);if(rv!=NGX_CONF_OK){gotofailed;}
#1 检查模块是否提供了 merge_loc_conf 回调函数。 如果存在,则需要进行 location 级别的配置合并。 模块可能只关心 server 级配置而不关心 location 级,通过判断避免无谓操作
#2 将当前上下文 ctx 的 loc_conf 指针指向当前 server 的 loc_conf 数组
#3 调用模块的 merge_loc_conf 函数, 合并 server 级别的 location 配置(即 server 块中直接出现的与 location 相关的指令) 参数: cf:配置上下文。 saved.loc_conf[ctx_index]: 父级(主层级)的 location 配置。 cscfp[s]->ctx->loc_conf[ctx_index]: 当前 server 的 location 配置。 合并后得到该 server 上 location 级指令的最终配置(此配置将作为 server 下所有 location 的默认父配置)。 完成 server 级 location 配置的继承,为后续 location 块合并提供正确的父级配置。

3-4 递归合并该 server 内部的所有 location 块
/* merge the locations{}' loc_conf's */clcf=cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];rv=ngx_http_merge_locations(cf,clcf->locations,cscfp[s]->ctx->loc_conf,module,ctx_index);if(rv!=NGX_CONF_OK){gotofailed;}}}
#1 获取当前 server 的核心模块(ngx_http_core_module)的 location 配置结构体 从当前 server 的 loc_conf 数组中,取出 HTTP Core 模块 的配置结构体。 loc_conf 是一个数组,存放了所有 HTTP 模块的配置指针。 ngx_http_core_module.ctx_index 是 Core 模块的固定索引。 clcf (ngx_http_core_loc_conf_t *) 是核心 location 级配置, 它包含了 locations 字段,这是一个树状结构,存储了该 server 下所有显式定义的 location {} 块。 获取 location 树。 只有 Core 模块维护了 location {} 的拓扑结构(前缀匹配、正则匹配等)。 其他业务模块(如 gzip)只关心配置数据,不关心 location 结构, 所以必须从 Core 模块获取 locations 树来进行递归合并。
#2 调用 ngx_http_merge_locations 函数, 递归合并该 server 下所有 location 块的配置。 参数: cf:配置上下文 clcf->locations: location 树的队列头,包含了所有顶层 location 块。 cscfp[s]->ctx->loc_conf: 当前 server 的 location 配置数组, 作为所有 location 的父级配置(默认值)。 module: 当前模块。 ctx_index: 模块索引。 该函数会遍历每个 location 块, 对每个 location 调用 merge_loc_conf, 并递归处理嵌套 location,实现完整的 location 配置合并。
#3 检查递归合并的结果。 出错时跳转到错误处理。

4 错误处理
failed:*ctx=saved;
恢复 原始上下文

5 返回处理结果
returnrv;}
http://www.cnnetsun.cn/news/1500326.html

相关文章:

  • 如何用PortProxyGUI简化Windows端口转发配置
  • XSS-Labs靶场通关秘籍:10种绕过过滤的实战技巧(附详细Payload)
  • Vitis 2021.2自定义IP编译受阻:从BSP驱动配置到手动文件补全的实战解决
  • 5G与IUV平台:技术融合如何加速移动通信创新
  • 保姆级教程:在Tina Linux (Allwinner T113) 上为UART1配置完整的调试串口功能
  • 基于WPF与OpenCV的高级显示控件2.0:集成拖拽显示与Adorner交互绘图新功能
  • 【Python异步I/O并发实战宝典】:20年CTO亲授asyncio+uvloop+trio高并发架构设计与压测调优秘籍
  • ag-grid 自定义下拉框编辑器:实现带搜索与新增功能的单元格编辑
  • Jetson开发者必看:JetPack版本与显卡驱动兼容性全解析(附避坑指南)
  • pyNastran:从文件解析到工程智能的革命性跨越
  • 飞行器设计避坑指南:盘点那些影响气动效率的‘隐形杀手’(从摩擦阻力到干扰阻力)
  • 从移位相加到硬件实现:FPGA二进制乘法器的设计精髓
  • Quixel Bridge桥接插件全攻略:从UE4到Blender的无缝资产迁移
  • 灵脉SAST实战:如何用AI大模型5分钟搞定Java代码审计(附真实案例)
  • 告别代码!用Excel联动Arcgis属性表,5分钟搞定字段排序与自动编号
  • 终极指南:BepInEx三步解锁Unity游戏无限可能
  • LangGraph 工作流实战:Few-Shot提示赋能大模型精准调用自定义计算工具
  • PathOfBuilding全维度解析:7步掌握流放之路角色构建的效率倍增工具
  • 鸿蒙Image图片处理实战:5分钟搞定图片解码与编码(附完整代码)
  • 三步打造你的专属阅读空间:开源阅读鸿蒙版深度体验
  • 【KingbaseES】Linux环境下KESV8授权文件license.dat的快速替换指南
  • Apache IoTDB Web Workbench:零基础掌握时序数据库可视化管理的颠覆式工具
  • Win11 绕过 TPM 或 CPU 检测的 3 种实用方法
  • 2026年3月24隔夜暗盘挂单排行榜
  • 手把手教你清理vSphere Replication 6.5的残留注册信息(解决OVF部署失败)
  • 别再为气象数据发愁!手把手教你用HYSPLIT做后向轨迹分析(附GDAS1数据下载指南)
  • 多租户下的系统基础表设计
  • 3步解锁Windows LTSC新体验:商店恢复完全指南
  • Ncorr 2D:重塑开源数字图像相关技术的测量范式
  • 别再手动del了!Python智能体内存管理自动化配置指南(含实时监控+自适应阈值算法)