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

相关推荐
洛菡夕13 小时前
nginx安全防护与HTTPS部署实战
nginx·安全·https
刘晨鑫117 小时前
Nginx性能调优
运维·nginx
**蓝桉**17 小时前
prometheus监控nginx
nginx·elasticsearch·prometheus
sszdzq21 小时前
docker 安装 Nginx
nginx·docker·容器
我爱学习好爱好爱1 天前
ELK 7.17.10 + Redis 5.0.7 构建高可用 Nginx 日志收集系统(Rocky Linux 9.6 实战)
redis·nginx·elk
kc胡聪聪1 天前
nginx的性能优化与监控
运维·nginx·性能优化
zzh0811 天前
nginx安全笔记
笔记·nginx·安全
A10169330711 天前
Nginx 之Rewrite 使用详解
运维·nginx
vanvivo2 天前
Nginx中如何配置WebSocket代理?
运维·websocket·nginx
Java小白笔记2 天前
Nginx中配置IP白名单动态刷新
运维·tcp/ip·nginx