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

相关推荐
北风toto1 小时前
Windows 下用 OpenSSL 生成 SSL 密钥并配置 Nginx 教程
windows·nginx·ssl
卜锦元3 小时前
Docker Compose 部署 Nginx 1.30.6 完整指南
nginx·docker·容器
小小龙学IT5 小时前
Nginx 开源 Web 服务器与反向代理深度解
前端·nginx·开源
Coisinier1 天前
docker命令管理镜像及容器
linux·运维·nginx·docker·容器·操作系统
2301_32241428041 天前
基于web的校园失物招领管理系统59695-计算机毕设 原创(免费领源码+部署教程+开发环境)
mysql·nginx·php·apache·thinkphp·phpstudy·wampserver
flytalei1 天前
从YAML到Nginx服务访问:动手理解 Kubernetes Pod、Deployment 与 Service
运维·nginx·kubernetes
健康活着就好2 天前
# Nginx负载均衡四种策略,从原理到配置
nginx
Vitaliy Kostrov(柯维远)2 天前
谁来承担额外工作?CDN 参与者如何协商资源
nginx·缓存·系统架构·开源·cdn
北城笑笑2 天前
Server 18 ,Nginx 双服务器 HTTP转HTTPS 代理实战( HTTP 地址换 HTTPS 域名 )
运维·服务器·前端·后端·nginx·http·https