1 定义
ngx_http_init_static_location_trees 函数 定义在 ./nginx-1.24.0/src/http/ngx_http.c
staticngx_int_tngx_http_init_static_location_trees(ngx_conf_t*cf,ngx_http_core_loc_conf_t*pclcf){ngx_queue_t*q,*locations;ngx_http_core_loc_conf_t*clcf;ngx_http_location_queue_t*lq;locations=pclcf->locations;if(locations==NULL){returnNGX_OK;}if(ngx_queue_empty(locations)){returnNGX_OK;}for(q=ngx_queue_head(locations);q!=ngx_queue_sentinel(locations);q=ngx_queue_next(q)){lq=(ngx_http_location_queue_t*)q;clcf=lq->exact?lq->exact:lq->inclusive;if(ngx_http_init_static_location_trees(cf,clcf)!=NGX_OK){returnNGX_ERROR;}}if(ngx_http_join_exact_locations(cf,locations)!=NGX_OK){returnNGX_ERROR;}ngx_http_create_locations_list(locations,ngx_queue_head(locations));pclcf->static_locations=ngx_http_create_locations_tree(cf,locations,0);if(pclcf->static_locations==NULL){returnNGX_ERROR;}returnNGX_OK;}
ngx_http_init_static_location_trees 函数的主要作用是 在配置解析阶段,递归地初始化静态 location 树(static location trees), 用于后续请求处理时快速匹配 location。
2 详解
1 函数签名
staticngx_int_tngx_http_init_static_location_trees(ngx_conf_t*cf,ngx_http_core_loc_conf_t*pclcf)
返回值 NGX_OK:成功。 NGX_ERROR:失败
参数 ngx_conf_t *cf 指向配置解析上下文 ngx_http_core_loc_conf_t *pclcf 父级的 http_core_loc_conf_t 结构体指针。 它代表当前正在处理的作用域(通常是一个 server 块,或者是嵌套的 location 块)。
2 逻辑流程
1 局部变量 2 locations 链表检查 3 遍历递归 4 合并 5 排序 6 构建二叉查找树 7 返回成功
1 局部变量
{ngx_queue_t*q,*locations;ngx_http_core_loc_conf_t*clcf;ngx_http_location_queue_t*lq;
2 locations 链表检查
locations=pclcf->locations;if(locations==NULL){returnNGX_OK;}if(ngx_queue_empty(locations)){returnNGX_OK;}
从父配置 pclcf 中获取其下属的 locations 链表(ngx_queue_t 类型)。 如果没有定义任何 location,或者列表为空,则直接返回成功(NGX_OK),无需构建树。
3 遍历递归
for(q=ngx_queue_head(locations);q!=ngx_queue_sentinel(locations);q=ngx_queue_next(q)){lq=(ngx_http_location_queue_t*)q;clcf=lq->exact?lq->exact:lq->inclusive;if(ngx_http_init_static_location_trees(cf,clcf)!=NGX_OK){returnNGX_ERROR;}}
遍历父 location 的所有直接子 location, 并对每个子 location 递归地调用自身, 以构建其内部的静态 location 树
4 合并
if(ngx_http_join_exact_locations(cf,locations)!=NGX_OK){returnNGX_ERROR;}
将同一层级内具有相同名称的精确匹配和前缀匹配 location 合并到同一个节点中
5 排序
ngx_http_create_locations_list(locations,ngx_queue_head(locations));
6 构建二叉查找树
pclcf->static_locations=ngx_http_create_locations_tree(cf,locations,0);if(pclcf->static_locations==NULL){returnNGX_ERROR;}
使用整理排序后的链表 来构建二叉查找树
7 返回成功
returnNGX_OK;}