staticngx_int_tngx_http_join_exact_locations(ngx_conf_t*cf,ngx_queue_t*locations){ngx_queue_t*q,*x;ngx_http_location_queue_t*lq,*lx;q=ngx_queue_head(locations);while(q!=ngx_queue_last(locations)){x=ngx_queue_next(q);lq=(ngx_http_location_queue_t*)q;lx=(ngx_http_location_queue_t*)x;if(lq->name->len==lx->name->len&&ngx_filename_cmp(lq->name->data,lx->name->data,lx->name->len)==0){if((lq->exact&&lx->exact)||(lq->inclusive&&lx->inclusive)){ngx_log_error(NGX_LOG_EMERG,cf->log,0,"duplicate location \"%V\" in %s:%ui",lx->name,lx->file_name,lx->line);returnNGX_ERROR;}lq->inclusive=lx->inclusive;ngx_queue_remove(x);continue;}q=ngx_queue_next(q);}returnNGX_OK;}
ngx_http_join_exact_locations 函数的作用是 将 URI 相同的精确匹配(location = /uri)和前缀匹配(location /uri)合并到同一个链表节点中。
q=ngx_queue_head(locations);while(q!=ngx_queue_last(locations)){x=ngx_queue_next(q);lq=(ngx_http_location_queue_t*)q;lx=(ngx_http_location_queue_t*)x;if(lq->name->len==lx->name->len&&ngx_filename_cmp(lq->name->data,lx->name->data,lx->name->len)==0){if((lq->exact&&lx->exact)||(lq->inclusive&&lx->inclusive)){ngx_log_error(NGX_LOG_EMERG,cf->log,0,"duplicate location \"%V\" in %s:%ui",lx->name,lx->file_name,lx->line);returnNGX_ERROR;}lq->inclusive=lx->inclusive;ngx_queue_remove(x);continue;}q=ngx_queue_next(q);}