当前位置: 首页 > news >正文

ngx_http_find_virtual_server

1 定义

ngx_http_find_virtual_server 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.c
staticngx_int_tngx_http_find_virtual_server(ngx_connection_t*c,ngx_http_virtual_names_t*virtual_names,ngx_str_t*host,ngx_http_request_t*r,ngx_http_core_srv_conf_t**cscfp){ngx_http_core_srv_conf_t*cscf;if(virtual_names==NULL){returnNGX_DECLINED;}cscf=ngx_hash_find_combined(&virtual_names->names,ngx_hash_key(host->data,host->len),host->data,host->len);if(cscf){*cscfp=cscf;returnNGX_OK;}#if(NGX_PCRE)if(host->len&&virtual_names->nregex){ngx_int_tn;ngx_uint_ti;ngx_http_server_name_t*sn;sn=virtual_names->regex;#if(NGX_HTTP_SSL&&defined SSL_CTRL_SET_TLSEXT_HOSTNAME)if(r==NULL){ngx_http_connection_t*hc;for(i=0;i<virtual_names->nregex;i++){n=ngx_regex_exec(sn[i].regex->regex,host,NULL,0);if(n==NGX_REGEX_NO_MATCHED){continue;}if(n>=0){hc=c->data;hc->ssl_servername_regex=sn[i].regex;*cscfp=sn[i].server;returnNGX_OK;}ngx_log_error(NGX_LOG_ALERT,c->log,0,ngx_regex_exec_n" failed: %i ""on \"%V\" using \"%V\"",n,host,&sn[i].regex->name);returnNGX_ERROR;}returnNGX_DECLINED;}#endif/* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */for(i=0;i<virtual_names->nregex;i++){n=ngx_http_regex_exec(r,sn[i].regex,host);if(n==NGX_DECLINED){continue;}if(n==NGX_OK){*cscfp=sn[i].server;returnNGX_OK;}returnNGX_ERROR;}}#endif/* NGX_PCRE */returnNGX_DECLINED;}
ngx_http_find_virtual_server 函数用于 根据 HTTP 请求的主机名(`Host` 头) 在监听端口的虚拟主机名集合中查找对应的 `server` 配置。 它优先进行精确及通配符哈希查找, 若失败则按顺序尝试正则匹配(支持 SSL SNI 阶段的特殊处理), 最终返回匹配到的虚拟服务器配置或未找到标志。

2 详解

1 函数签名

staticngx_int_tngx_http_find_virtual_server(ngx_connection_t*c,ngx_http_virtual_names_t*virtual_names,ngx_str_t*host,ngx_http_request_t*r,ngx_http_core_srv_conf_t**cscfp)
返回值 NGX_OK:成功找到匹配的虚拟服务器,*cscfp 已指向对应配置。 NGX_DECLINED:未找到任何匹配,调用者应使用默认服务器。 NGX_ERROR:匹配过程中发生严重错误,应中断当前连接。
参数1 ngx_connection_t *c 当前连接
参数2 ngx_http_virtual_names_t *virtual_names 指向 该地址端口下的虚拟主机名集合
参数3 ngx_str_t *host 表示待匹配的主机名
参数4 ngx_http_request_t *r 指向 当前 HTTP 请求结构体的指针,可以为 NULL
参数5 ngx_http_core_srv_conf_t **cscfp 指向服务器配置指针的指针(二级指针) 输出参数,当查找成功时, 将 *cscfp 设置为匹配到的 server 块配置。 查找失败时不修改。

2 逻辑流程

1 局部变量 2 空集合检查 3 hash 查找 4 查找成功 5 正则相关处理 6 未匹配

1 局部变量
{ngx_http_core_srv_conf_t*cscf;
cscf:类型为指向服务器核心配置的指针, 用于暂存哈希查找的结果,初始值未定义

2 空集合检查
if(virtual_names==NULL){returnNGX_DECLINED;}
空指针检查: 若传入的虚拟主机名集合为 NULL (通常意味着当前监听端口未配置任何 server_name), 则立即返回 NGX_DECLINED,表示未找到匹配, 调用者会使用默认服务器。 这避免了对空指针的非法访问。

3 hash 查找
cscf=ngx_hash_find_combined(&virtual_names->names,ngx_hash_key(host->data,host->len),host->data,host->len);
精确/通配哈希查找: 调用 ngx_hash_find_combined 在组合哈希表 virtual_names->names 中查找。 该哈希表同时存储了精确名称、前缀通配符(*.example.com)和后缀通配符(www.*)。 ngx_hash_key(host->data, host->len) 计算主机名字符串的哈希值(BKDR 哈希算法),用于定位桶。 后两个参数传递原始字符串和长度,用于在桶内逐字比对,防止哈希碰撞。 返回匹配到的 ngx_http_core_srv_conf_t 指针,若未找到则为 NULL。

4 查找成功
if(cscf){*cscfp=cscf;returnNGX_OK;}
检查哈希查找结果: 若 cscf 非空,说明成功匹配。 *cscfp = cscf: 将输出参数指向该服务器配置。 返回 NGX_OK,调用者即可使用 *cscfp 获得服务器配置。

5 正则相关处理
#if(NGX_PCRE)if(host->len&&virtual_names->nregex){ngx_int_tn;ngx_uint_ti;ngx_http_server_name_t*sn;sn=virtual_names->regex;#if(NGX_HTTP_SSL&&defined SSL_CTRL_SET_TLSEXT_HOSTNAME)if(r==NULL){ngx_http_connection_t*hc;for(i=0;i<virtual_names->nregex;i++){n=ngx_regex_exec(sn[i].regex->regex,host,NULL,0);if(n==NGX_REGEX_NO_MATCHED){continue;}if(n>=0){hc=c->data;hc->ssl_servername_regex=sn[i].regex;*cscfp=sn[i].server;returnNGX_OK;}ngx_log_error(NGX_LOG_ALERT,c->log,0,ngx_regex_exec_n" failed: %i ""on \"%V\" using \"%V\"",n,host,&sn[i].regex->name);returnNGX_ERROR;}returnNGX_DECLINED;}#endif/* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */for(i=0;i<virtual_names->nregex;i++){n=ngx_http_regex_exec(r,sn[i].regex,host);if(n==NGX_DECLINED){continue;}if(n==NGX_OK){*cscfp=sn[i].server;returnNGX_OK;}returnNGX_ERROR;}}#endif/* NGX_PCRE */

6 未匹配
returnNGX_DECLINED;}
最终未匹配: 如果哈希表和所有正则(如果有)都未找到, 返回 NGX_DECLINED。 调用者将使用监听端口的默认服务器。
http://www.jsqmd.com/news/873267/

相关文章:

  • 电气安全回路设计实战:皮尔兹安全继电器应用
  • 北京家电回收-北京电器回收-北京中央空调回收-北京旧空调回收电话 - 资讯纵览
  • 如何3步掌握PAGExporter:After Effects动画跨平台导出的完整实战指南
  • 国内高校毕业生必备的AI论文写作软件是哪款?
  • 【夏日焕肤三件套|补水+修护+净透,解锁水光肌密码】
  • 高防CDN实战:安全防护与访问加速一体化方案
  • 突破限制:如何用RDP Wrapper解锁Windows远程桌面多人连接功能
  • 写给新手的 tensorflow:昇腾 TensorFlow 适配到底是啥?
  • Anthropic 企业采用率首次反超 OpenAI:Ramp 5 月数据复盘
  • 挖码AI助手实战评测:一个平台搞定文生视频、PPT与对话,多模型切换到底有多强?
  • 日常办公必备:2026实测几种主流PDF压缩工具推荐分享 - 时讯资讯
  • 市场比较好的石牌坊品牌推荐,单门石牌坊/花岗岩石牌坊/石牌坊/石雕石牌坊/复式石牌坊,石牌坊公司推荐 - 品牌推荐师
  • 从零搭建政务AI Agent系统:37个部委级审批节点穿透解析,含国产化信创环境适配清单(麒麟V10+昇腾910B实测版)
  • nginx中间代理。前端下载资源跨域,太大不想放到服务端处理。
  • 核心优势驱动:Centric PLM如何破解跨境电商多市场协同难题
  • 用 MapleSim 卷绕和卷材加工仿真库加速智能制造与电池产线优化
  • 没有外机位也能装?厨房空调水冷方案全解:从散热原理到冷凝水回收 - 奔跑123
  • 抖音视频怎么提取无水印版本?2026年抖音无水印视频提取工具推荐 - 科技大爆炸
  • AI Agent写作如何重构内容生产力:3个已被验证的行业增效模型及ROI测算公式
  • 微电网协调控制柜 vs 传统配电柜:本质差异与代际跨越
  • 终极Scribd电子书下载指南:3步打造个人离线图书馆
  • 从“各卖各的”到“一盘棋”——服装老板用了怎样的ERP+分销系统
  • 2026年郑州企业做GEO优化怎样选择服务商?本地靠谱机构盘点解析 - 哈喽33
  • 2026年一键生成论文工具实测报告:5款神器从文献到降重一站式避坑指南
  • AIGC 内容安全检测服务精选公司:天磊卫士(深圳)科技有限公司
  • 这不是一个浪漫古士
  • RDPWrap完整指南:免费解锁Windows多用户远程桌面实用教程
  • 数据说话:驱动芯片的关键性能指标与设计挑战
  • 生产环境的“后悔药”:如何利用 Dify 版本控制与回滚机制建立 AI 应用的 CI/CD 闭环?
  • 豆包获客讲师:深度专业评估与独家解析