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

ngx_http_add_location

声明在 src\http\ngx_http_core_module.c 

ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
    ngx_http_core_loc_conf_t *clcf);

定义在 src\http\ngx_http.c 

ngx_int_t
ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
    ngx_http_core_loc_conf_t *clcf)
{
    ngx_http_location_queue_t  *lq;

    if (*locations == NULL) {
        *locations = ngx_palloc(cf->temp_pool,
                                sizeof(ngx_http_location_queue_t));
        if (*locations == NULL) {
            return NGX_ERROR;
        }

        ngx_queue_init(*locations);
    }

    lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
    if (lq == NULL) {
        return NGX_ERROR;
    }

    if (clcf->exact_match
#if (NGX_PCRE)
        || clcf->regex
#endif
        || clcf->named || clcf->noname)
    {
        lq->exact = clcf;
        lq->inclusive = NULL;

    } else {
        lq->exact = NULL;
        lq->inclusive = clcf;
    }

    lq->name = &clcf->name;
    lq->file_name = cf->conf_file->file.name.data;
    lq->line = cf->conf_file->line;

    ngx_queue_init(&lq->list);

    ngx_queue_insert_tail(*locations, &lq->queue);

    if (ngx_http_escape_location_name(cf, clcf) != NGX_OK) {
        return NGX_ERROR;
    }

    return NGX_OK;
}

ngx_http_add_location 函数的作用是将一个新的 location 配置项添加到 Nginx 的 location 队列中,以便后续处理 HTTP 请求时进行匹配


ngx_int_t
ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
    ngx_http_core_loc_conf_t *clcf)
{
    ngx_http_location_queue_t  *lq;

    if (*locations == NULL) {
        *locations = ngx_palloc(cf->temp_pool,
                                sizeof(ngx_http_location_queue_t));
        if (*locations == NULL) {
            return NGX_ERROR;
        }

        ngx_queue_init(*locations);
    }

声明一个指向 ngx_http_location_queue_t 类型的指针 lq,用于后续存储新的 location 配置节点

ngx_http_location_queue_t-CSDN博客

判断传入的 locations 队列是否为空(未初始化)

如果队列未初始化(*locations == NULL),需要为其分配内存并初始化队列结构

此时 *locations=NULL

    lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
    if (lq == NULL) {
        return NGX_ERROR;
    }

 为新的 location 队列节点分配内存

    if (clcf->exact_match
#if (NGX_PCRE)
        || clcf->regex
#endif
        || clcf->named || clcf->noname)
    {
        lq->exact = clcf;
        lq->inclusive = NULL;

    } else {
        lq->exact = NULL;
        lq->inclusive = clcf;
    }
  • clcf->exact_match
    表示当前 location 是精确匹配 (如 location = /exact/ {})。
  • clcf->regex
    表示当前 location 使用正则表达式 (如 location ~ ^/regex/ {})。
    • 该条件受 NGX_PCRE 宏控制,仅在编译时启用 PCRE 库时生效。
  • clcf->named
    表示当前 location 是命名 location (如 location @name {}),通常用于内部跳转。
  • clcf->noname
    表示当前 location 是未命名的特殊 location (如 location / {} 的默认配置)

条件判断

如果当前 location 是以下类型之一:

exact_match= 精确匹配)

regex(正则表达式匹配,如 ~~*

named(命名 location,如 location @name

noname(无名 location,如 location {}

则将其标记为 exact 类型(高优先级)。

否则 (进入 else 分支),标记为 inclusive 类型(普通前缀匹配)。

字段赋值

exact = NULL:显式清空高优先级匹配指针。

inclusive = clcf:将当前 location 的配置结构体指针赋给 inclusive,表示这是一个普通前缀匹配的 location

Nginx 在路由请求时

按优先级顺序匹配 (精确匹配 > 正则匹配 > 普通前缀匹配)

此时 exact_match=0    regex=NULL   named=0    noname=0

    lq->name = &clcf->name;
    lq->file_name = cf->conf_file->file.name.data;
    lq->line = cf->conf_file->line;
 lq->name = &clcf->name;
  • 作用 :将 lqname 指针指向当前 location 配置的名称(clcf->name)。
  • 意义
    • clcf->namengx_str_t 类型,存储了 location 的匹配规则(如 /api~ ^/regex)。
    • 通过 lq->name 可以直接访问该名称,用于请求匹配时的调试输出 日志记录 (例如记录命中了哪个 location)。
 lq->file_name = cf->conf_file->file.name.data;
  • 作用 :将 lqfile_name 指向当前解析的配置文件路径(如 /etc/nginx/conf.d/default.conf)。
  • 意义
    • cf->conf_file->file.name.data 是一个字符串,表示当前解析的配置文件路径。
    • 在出现配置错误(如重复 location 或语法错误)时,Nginx 可以通过 file_name 定位到具体的配置文件 ,方便用户快速排查问题。
 lq->line = cf->conf_file->line;
  • 作用 :将 lqline 设置为当前解析的配置文件行号。
  • 意义
    • cf->conf_file->line 是一个整数,表示当前解析到的配置文件行号。
    • 结合 file_name,可以在错误日志中精确标识配置的位置 (例如 nginx.conf:15),提升调试效率。

此时

lq->name->data=/
lq->file_name=/home/wsd/桌面/nginx/conf/nginx.conf
lq->line=43 

    ngx_queue_init(&lq->list);

 初始化 ngx_http_location_queue_t 节点内部的子队列

若配置中存在嵌套的 location(如 location /parent { location /child {} }),父 location 的 list 可用于链接子节点

    ngx_queue_insert_tail(*locations, &lq->queue);

 将新节点添加到队列的末尾

    if (ngx_http_escape_location_name(cf, clcf) != NGX_OK) {
        return NGX_ERROR;
    }

 

  • 调用转义函数
    ngx_http_escape_location_name(cf, clcf)clcf->name(location 的名称)进行 URI 转义。
  • 错误检查
    如果转义失败(返回值非 NGX_OK),立即终止当前配置解析,返回 NGX_ERROR

ngx_http_escape_location_name-CSDN博客

return NGX_OK;

 返回 NGX_OK


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

相关文章:

  • 压测工具开发(一)——使用Qt Designer构建简单界面
  • 【漫话机器学习系列】154.岭回归(Ridge Regression)
  • JMeter JSON断言讲解和错误用例
  • kubernetes高级资源之污点和容忍
  • mapbox进阶,添加鹰眼图控件
  • 基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
  • 鸿蒙移动应用开发--UI组件布局
  • react中防止数据多大并需要二次加工处理进行单线程转多线程webworker优化处理(不借助react-webworker)
  • 代码随想录刷题day52|(二叉树篇)106.从中序与后序遍历序列构造二叉树
  • 大疆上云api如何配置开放平台
  • DM9162使用记录
  • Tekton系列之实践篇-从触发到完成的完整执行过程
  • 【无标题】QT相关练习
  • 框架的CVE漏洞利用 php类 java类 手工操作和自动化操作蓝队分析漏洞利用的流量特征
  • 力扣题(3):寻找两个正序数组的中位数
  • 纯HTML+CSS实现3D空间正方体旋转
  • Opencv计算机视觉编程攻略-第三节 图像颜色处理
  • 23种设计模式-中介者(Mediator)设计模式
  • 网关助力冶金厂电表数据高效采集与监控
  • 【Redis】redis实现消息的发布和订阅