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

相关推荐
yunqi12156 小时前
【负载均衡系列】nginx负载高怎么排查
运维·nginx·负载均衡
若云止水9 小时前
ngx_http_escape_location_name
nginx
餘yuqn12 小时前
项目部署后,nginx拦截请求后无法通过后端服务security放行规则
spring boot·nginx
fall_rain16 小时前
基于socket实现一个简易的web服务器——非阻塞的模式
nginx
fall_rain16 小时前
基于socket实现一个简易的web服务器
nginx
Seamon18 小时前
竞赛项目部署记录
java·nginx
ZZDICT18 小时前
OpenResty(Lua)+Redis实现动态封禁IP
redis·nginx·lua·openresty
Live in Shanxi.19 小时前
Nginx的HTTPS配置
运维·nginx·https
MacroZheng1 天前
解放双手!看看人家的Nginx可视化管理工具,确实清新优雅!
java·后端·nginx