ngx_http_core_location

定义在 src\http\ngx_http_core_module.c 

static char *
ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{char                      *rv;u_char                    *mod;size_t                     len;ngx_str_t                 *value, *name;ngx_uint_t                 i;ngx_conf_t                 save;ngx_http_module_t         *module;ngx_http_conf_ctx_t       *ctx, *pctx;ngx_http_core_loc_conf_t  *clcf, *pclcf;ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));if (ctx == NULL) {return NGX_CONF_ERROR;}pctx = cf->ctx;ctx->main_conf = pctx->main_conf;ctx->srv_conf = pctx->srv_conf;ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);if (ctx->loc_conf == NULL) {return NGX_CONF_ERROR;}for (i = 0; cf->cycle->modules[i]; i++) {if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {continue;}module = cf->cycle->modules[i]->ctx;if (module->create_loc_conf) {ctx->loc_conf[cf->cycle->modules[i]->ctx_index] =module->create_loc_conf(cf);if (ctx->loc_conf[cf->cycle->modules[i]->ctx_index] == NULL) {return NGX_CONF_ERROR;}}}clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];clcf->loc_conf = ctx->loc_conf;value = cf->args->elts;if (cf->args->nelts == 3) {len = value[1].len;mod = value[1].data;name = &value[2];if (len == 1 && mod[0] == '=') {clcf->name = *name;clcf->exact_match = 1;} else if (len == 2 && mod[0] == '^' && mod[1] == '~') {clcf->name = *name;clcf->noregex = 1;} else if (len == 1 && mod[0] == '~') {if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {return NGX_CONF_ERROR;}} else if (len == 2 && mod[0] == '~' && mod[1] == '*') {if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {return NGX_CONF_ERROR;}} else {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"invalid location modifier \"%V\"", &value[1]);return NGX_CONF_ERROR;}} else {name = &value[1];if (name->data[0] == '=') {clcf->name.len = name->len - 1;clcf->name.data = name->data + 1;clcf->exact_match = 1;} else if (name->data[0] == '^' && name->data[1] == '~') {clcf->name.len = name->len - 2;clcf->name.data = name->data + 2;clcf->noregex = 1;} else if (name->data[0] == '~') {name->len--;name->data++;if (name->data[0] == '*') {name->len--;name->data++;if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {return NGX_CONF_ERROR;}} else {if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {return NGX_CONF_ERROR;}}} else {clcf->name = *name;if (name->data[0] == '@') {clcf->named = 1;}}}pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];if (cf->cmd_type == NGX_HTTP_LOC_CONF) {/* nested location */#if 0clcf->prev_location = pclcf;
#endifif (pclcf->exact_match) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"location \"%V\" cannot be inside ""the exact location \"%V\"",&clcf->name, &pclcf->name);return NGX_CONF_ERROR;}if (pclcf->named) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"location \"%V\" cannot be inside ""the named location \"%V\"",&clcf->name, &pclcf->name);return NGX_CONF_ERROR;}if (clcf->named) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"named location \"%V\" can be ""on the server level only",&clcf->name);return NGX_CONF_ERROR;}len = pclcf->name.len;#if (NGX_PCRE)if (clcf->regex == NULL&& ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
#elseif (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
#endif{ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"location \"%V\" is outside location \"%V\"",&clcf->name, &pclcf->name);return NGX_CONF_ERROR;}}if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {return NGX_CONF_ERROR;}save = *cf;cf->ctx = ctx;cf->cmd_type = NGX_HTTP_LOC_CONF;rv = ngx_conf_parse(cf, NULL);*cf = save;return rv;
}

该函数是 Nginx 解析 location 配置块的核心实现,负责:

  1. 解析 location 语法 :支持精确匹配(=)、前缀匹配(^~)、正则表达式(~~*)及命名 location(@)。
  2. 创建配置上下文 :为当前 location 块初始化模块配置结构体。
  3. 管理嵌套规则 :确保 location 块的嵌套符合 Nginx 语法限制(如禁止在精确匹配或命名 location 内嵌套)。
  4. 注册 location 到父级配置 :将解析后的 location 添加到所属父级(server 或上层 location)的配置中。

    ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));if (ctx == NULL) {return NGX_CONF_ERROR;}

 为 location 块创建独立的配置上下文 ,用于存储该作用域内的模块配置数据

ngx_http_conf_ctx_t -CSDN博客

    pctx = cf->ctx;ctx->main_conf = pctx->main_conf;ctx->srv_conf = pctx->srv_conf;

 继承父级配置上下文 ,确保 location 块可以复用父级(httpserver 块)的全局配置,同时允许独立覆盖或扩展自己的 loc_conf。 

  • main_conf :所有 location 共享同一份 http 配置。
  • srv_conf :同一 server 下的所有 location 共享 server 配置。
  • loc_conf :每个 location 独立,用于覆盖或扩展配置。
    ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);if (ctx->loc_conf == NULL) {return NGX_CONF_ERROR;}

location 块的模块配置分配存储空间 ,确保每个 HTTP 模块可以在当前作用域(location)中存储自己的配置数据

    for (i = 0; cf->cycle->modules[i]; i++) {if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {continue;}module = cf->cycle->modules[i]->ctx;if (module->create_loc_conf) {ctx->loc_conf[cf->cycle->modules[i]->ctx_index] =module->create_loc_conf(cf);if (ctx->loc_conf[cf->cycle->modules[i]->ctx_index] == NULL) {return NGX_CONF_ERROR;}}}

 为每个 HTTP 模块初始化 location 级别的配置结构体 

    clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];clcf->loc_conf = ctx->loc_conf;

 将当前 location 的配置上下文(loc_conf 数组)关联到核心模块的配置结构体中 ,使得核心模块能够访问所有模块的配置数据,协调请求处理流程 

ngx_http_core_loc_conf_t-CSDN博客

    value = cf->args->elts;

获取指令的参数列表

    if (cf->args->nelts == 3) {
参数数量检查
  • cf->args->nelts
    表示当前配置指令(如 location)的参数数量。
    • nelts == 3 :用户使用了显式修饰符(如 location = /exact)。
    • nelts == 2 :用户未显式指定修饰符

此时 cf->args->nelts=2

条件不成立

进入 else 

else {name = &value[1];

获取 location 指令的第一个参数

此时 name->data=/

        if (name->data[0] == '=') {

 此时条件不成立

 

} else if (name->data[0] == '^' && name->data[1] == '~') {

此时 条件不成立

} else if (name->data[0] == '~') {

此时 条件不成立

 

        } else {clcf->name = *name;if (name->data[0] == '@') {clcf->named = 1;}}

namelocation 指令的路径参数(如 value[1],即用户配置中的第二个参数)。

将路径字符串赋值给核心模块配置结构体的 name 字段

此时 这里的 if 条件不成立

pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];

 获取父级 location 的核心模块配置 ,用于校验嵌套规则或继承配置

通过索引从父级的 loc_conf 数组中获取核心模块的配置结构体

指向父级 location 的核心模块配置结构体

if (cf->cmd_type == NGX_HTTP_LOC_CONF) {

判断当前是否处于 location 块的配置解析阶段

此时 cf->cmd_type=4000000      NGX_HTTP_LOC_CONF=8000000

条件不成立,当前还未进入 location 块内部配置解析的阶段

    if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {return NGX_CONF_ERROR;}

将新解析的 location 配置添加到父级(server 或上层 location)的链表中 ,确保请求处理时能够遍历所有 location 进行匹配。

  • ngx_http_add_location 函数 :
    • 功能 :将当前 locationclcf)添加到父级的 locations 链表(pclcf->locations)。
    • 参数 :
      • cf:配置解析上下文。
      • &pclcf->locations:父级的 locations 链表指针。
      • clcf:当前 location 的核心模块配置结构体。

locations 链表 :
存储所有 location 配置

ngx_http_add_location-CSDN博客 

    save = *cf;cf->ctx = ctx;cf->cmd_type = NGX_HTTP_LOC_CONF;rv = ngx_conf_parse(cf, NULL);*cf = save;

 

save = *cf;

  • 保存当前配置解析上下文。
  • 逻辑 :
    • cf 是指向当前配置解析上下文(ngx_conf_t 结构)的指针。
    • save 是一个局部变量,类型为 ngx_conf_t
    • 通过 *cf 解引用操作,将当前配置解析状态(包括上下文指针、命令类型等)完整复制到 save 中。
  • 意义 :
    • 在后续解析 location 块时,会临时修改 cf 的上下文。此操作保存原始状态,以便解析完成后恢复。

cf->ctx = ctx;

  • 作用 :切换配置上下文到当前 location 的上下文。
  • 逻辑 :
    • ctx 是新创建的 ngx_http_conf_ctx_t 结构,专用于当前 location 块。
    • cf->ctx 是配置解析的核心上下文指针,指向当前生效的配置存储结构。
    • cf->ctx 指向新的 ctx,使得后续解析的指令会将配置存储到该 location 的上下文中。

 cf->cmd_type = NGX_HTTP_LOC_CONF;

  • 作用 :设置当前解析的指令类型为 "HTTP Location 配置"。
  • 逻辑 :
    • cmd_typengx_conf_t 中的字段,用于标识当前解析的指令类型。
    • NGX_HTTP_LOC_CONF 表示接下来解析的指令属于 location 块。
  • 意义 :
    • 指令过滤 :Nginx 根据 cmd_type 调用对应模块的指令处理函数。例如,只有声明为 NGX_HTTP_LOC_CONF 类型的指令会被处理,其他指令(如 server 级指令)会触发错误。

rv = ngx_conf_parse(cf, NULL);

  • 作用 :解析 location 块内的配置指令。
  • 逻辑 :
    • ngx_conf_parse 是 Nginx 的核心配置解析函数。
    • 传入 cf(已切换到 location 上下文)和 NULL(表示继续解析当前配置流,而非新文件)。
    • 返回值 rv 表示解析结果(成功或错误码)。
  • 意义 :
    • 递归解析 :处理 location 块内的所有指令

ngx_conf_parse - location块-CSDN博客


*cf = save;

  • 作用 :恢复原始配置解析上下文。
  • 逻辑 :
    • 将之前保存的 save 值复制回 cf,覆盖当前修改后的 cf 状态。
    • 恢复字段包括 ctx(父级上下文)和 cmd_type(如 server 级指令类型)。
  • 意义 :
    • 上下文回退 :确保解析完当前 location 后,父级配置解析(如 server 块)能继续正确执行。
    • 避免污染 :防止 location 的临时配置影响后续指令的解析。

整体逻辑总结

  1. 保存现场 :备份父级配置上下文。
  2. 切换上下文 :为 location 块创建独立的配置存储空间。
  3. 标记指令类型 :确保仅处理 location 级指令。
  4. 解析子配置 :处理 location 内的所有指令。
  5. 恢复现场 :回到父级配置解析流程。
return rv;

返回 NGX_CONF_OK

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

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

相关文章

全面讲解python的uiautomation包

在常规的模拟鼠标和键盘操作,我们一般使用pyautogui,uiautomation模块不仅能直接支持这些操作,还能通过控件定位方式直接定位到目标控件的位置,而不需要自己去获取对应坐标位置。uiautomation模块不仅支持任意坐标位置截图&#x…

图解CNN、RNN、LSTM

一、CNN 二、RNN 三、LSTM 以上笔记参考自b站up主 自然卷小蛮(自然卷小蛮的个人空间-自然卷小蛮个人主页-哔哩哔哩视频),感兴趣的可以去深入了解。

3.25学习总结 抽象类和抽象方法+接口+内部类+API

抽象类和抽象方法: 有抽象方法,那么类肯定是抽象类。父类不一定是抽象的,但如果父类中有抽象方法那一定是抽象类。 如果子类中都存在吃这个行为,但吃的具体东西不同,那么吃这个行为定义在父类里面就是抽象方法&#x…

Ubuntu22.04 UEFI系统配置Apache Tomcat/8.5.87为开机自动启动

前置条件,Java与Tomcat目录均为/usr/local路径下。 java安装目录为:/usr/local/java tomcat安装目录为:/usr/local/tomcat 1. 创建 Tomcat 专用用户和组(可选但推荐) # 创建 tomcat 用户组 sudo groupadd tomcat#…

MySQL复习

1基本操作复习 1.1数据库创建 创建数据库create database 数据库名;判断再创建数据库create database if not exists 数据库名;创建数据库指定字符集create database 数据库名 character set 字符集;创建数据库指定排序方式create database 数据库名 collate 排序方式;创建数据…

数据结构—树(java实现)

目录 一、树的基本概念1.树的术语2.常见的树结构 二、节点的定义三、有关树结构的操作1.按照数组构造平衡 二叉搜索树2.层序遍历树3.前、中、后序遍历树(1).前序遍历树(2).中序遍历树(3).后序遍历树(4).各种遍历的情况的效果对比 4.元素添加5.元素删除1.删除叶子节点2.删除单一…

SPI 机制与 Spring Boot AutoConfiguration 对比解析

一、架构效率革命性提升 1.1 类加载效率跃升 Spring Boot 2.7引入的AutoConfiguration.imports采用清单式配置加载,对比传统SPI机制: 传统SPI扫描路径:META-INF/services/** Spring Boot新方案:META-INF/spring/org.springfram…

node-red dashboard

安装: npm install node-red-dashboard 访问: http://127.0.0.1:1880/ui 1. 创建一个新的 Dashboard 页面: 在 Node-RED 编辑器中,拖动一个 ui_dashboard 节点到工作区,并将其连接到你的数据流。 2. 配置 Dashboard 节点: 双击…

深入理解现代C++在IT行业中的核心地位与应用实践

深入理解现代C在IT行业中的核心地位与应用实践 一、C在IT行业中的不可替代性 现代IT行业中,C凭借其零成本抽象和系统级控制能力,在以下关键领域保持不可替代地位: 应用领域C优势体现典型应用案例高性能计算直接内存管理,SIMD指令…

医院挂号预约小程序|基于微信小程序的医院挂号预约系统设计与实现(源码+数据库+文档)

医院挂号预约小程序 目录 基于微信小程序的医院挂号预约系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序用户端 2、系统服务端 (1) 用户管理 (2)医院管理 (3)医生管理 &#xf…

2025最新版Ubuntu Server版本Ubuntu 24.04.2 LTS下载与安装-详细教程,细致到每一步都有说明

官网 https://ubuntu.com/ 下载 点击菜单 Prodercts> Ubuntu OS>Ubuntu Server 点击下载 下载后会有个弹窗 安装 选择第一个 install Ubuntu Server 直接默认,选择English 【默认】 选择键盘布局【默认】 选择安装配置【默认】 配置网络 我这里选择…

【AI】NLP

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

vscode正则表达式使用

小标题 ^\d.\d.\d\s.*$ ^表示匹配字符串的开头。\d\.\d\.\d表示匹配一到多个数字,接着一个小数点,再接着一到多个数字,然后又一个小数点和一到多个数字,用来匹配类似 “2.1.1” 这样的标题号部分。\s表示匹配一个空格。.*表示匹配…

TCP/IP三次握手的过程,为什么要3次?

一:过程 第一次(SYN): 客户端发送一个带有SYN标志的TCP报文段给服务器,设置SYN1,并携带初始序列号Seqx(随机值),进入SYN_SENT状态。等待服务器相应。 第二次&#xff08…

vue-将组件内容导出为Word文档-docx

1. 安装依赖 首先,我们需要安装docx库,以便在前端生成Word文档。可以通过以下命令进行安装: npm install docx 2. 实现导出功能 2.1 初始化文档 使用docx库创建一个新的文档实例,并定义文档的结构和内容。我们使用Document、…

uni-app常用模板

列表样式一 ,下拉翻页查询,效果图及代码 <template><z-paging ref="paging" v-model="dataList" @query="queryList"><!-- 需要固定在顶部不滚动的view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot=&q…

鸿蒙移动应用开发--UI组件布局

实验要求&#xff1a; 制作一个B站视频卡片界面&#xff0c;大致如下图所示&#xff0c;要求应用到线性布局、层叠布局等相关课堂知识。背景图、logo及文本内容不限。 实验环境 &#xff1a;DevEco Studio 实验过程&#xff1a; 步骤1&#xff1a;创建项目 1. 在您的开发环境…

NVIDIA TensorRT 深度学习推理加速引擎详解

NVIDIA TensorRT 深度学习推理加速引擎详解 文章目录 NVIDIA TensorRT 深度学习推理加速引擎详解引言文章结构 第一部分&#xff1a;TensorRT概述什么是TensorRT&#xff1f;TensorRT的核心功能和优势1. 图优化2. 量化支持3. 动态形状支持4. 多平台支持5. 编程接口6. 性能优势 …

如何用Spring AI构建MCP Client-Server架构

现代 Web 应用正加速与大语言模型(LLMs)深度融合,构建超越传统问答场景的智能解决方案。为突破模型知识边界,增强上下文理解能力,开发者普遍采用多源数据集成策略,将 LLM 与搜索引擎、数据库、文件系统等外部资源互联。然而,异构数据源的协议差异与格式壁垒,往往导致集…

gradio调用多个CSS的HTML页

很多博客介绍的gradio读取html和css比较简单&#xff0c;如果要做很细致的前端页面优化&#xff0c;比如丰富的响应式的cssjs&#xff0c;至少要有html多个css&#xff0c;是暂不能实现的。bootstrap、font-awesome、jquery等 方案一当然是直接更换htmlcss为主的部署方式&#…