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

ngx_http_set_virtual_server

1 定义

ngx_http_set_virtual_server 函数 定义在 ./nginx-1.24.0/src/http/ngx_http_request.c
staticngx_int_tngx_http_set_virtual_server(ngx_http_request_t*r,ngx_str_t*host){ngx_int_trc;ngx_http_connection_t*hc;ngx_http_core_loc_conf_t*clcf;ngx_http_core_srv_conf_t*cscf;#if(NGX_SUPPRESS_WARN)cscf=NULL;#endifhc=r->http_connection;#if(NGX_HTTP_SSL&&defined SSL_CTRL_SET_TLSEXT_HOSTNAME)if(hc->ssl_servername){if(hc->ssl_servername->len==host->len&&ngx_strncmp(hc->ssl_servername->data,host->data,host->len)==0){#if(NGX_PCRE)if(hc->ssl_servername_regex&&ngx_http_regex_exec(r,hc->ssl_servername_regex,hc->ssl_servername)!=NGX_OK){ngx_http_close_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_ERROR;}#endifreturnNGX_OK;}}#endifrc=ngx_http_find_virtual_server(r->connection,hc->addr_conf->virtual_names,host,r,&cscf);if(rc==NGX_ERROR){ngx_http_close_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_ERROR;}#if(NGX_HTTP_SSL&&defined SSL_CTRL_SET_TLSEXT_HOSTNAME)if(hc->ssl_servername){ngx_http_ssl_srv_conf_t*sscf;if(rc==NGX_DECLINED){cscf=hc->addr_conf->default_server;rc=NGX_OK;}sscf=ngx_http_get_module_srv_conf(cscf->ctx,ngx_http_ssl_module);if(sscf->verify){ngx_log_error(NGX_LOG_INFO,r->connection->log,0,"client attempted to request the server name ""different from the one that was negotiated");ngx_http_finalize_request(r,NGX_HTTP_MISDIRECTED_REQUEST);returnNGX_ERROR;}}#endifif(rc==NGX_DECLINED){returnNGX_OK;}r->srv_conf=cscf->ctx->srv_conf;r->loc_conf=cscf->ctx->loc_conf;clcf=ngx_http_get_module_loc_conf(r,ngx_http_core_module);ngx_set_connection_log(r->connection,clcf->error_log);returnNGX_OK;}
ngx_http_set_virtual_server 函数的作用是: 根据 HTTP 请求的 `Host` 头,为请求选定并设置对应的虚拟主机(`server` 块)配置。

2 详解

1 函数签名

staticngx_int_tngx_http_set_virtual_server(ngx_http_request_t*r,ngx_str_t*host)
返回值 NGX_OK:成功设置了请求对应的虚拟主机配置 NGX_ERROR:发生错误
参数1 ngx_http_request_t *r 指向当前正在处理的请求的上下文环境
参数2 ngx_str_t *host 解析出的主机名

2 逻辑流程

1 局部变量 2 SSL 快速匹配路径 3 查找虚拟主机 4 错误检查 5 SSL 处理 6 未匹配 7 更新请求的配置 8 返回 成功

1 局部变量
{ngx_int_trc;ngx_http_connection_t*hc;ngx_http_core_loc_conf_t*clcf;ngx_http_core_srv_conf_t*cscf;#if(NGX_SUPPRESS_WARN)cscf=NULL;#endifhc=r->http_connection;
rc 用于保存函数调用的返回值,记录操作结果状态 hc 将指向当前请求关联的 HTTP 连接结构体(r->http_connection), 可从中获取地址配置信息等。 clcf 将指向核心模块(ngx_http_core_module)的 location 级配置, 主要用于后续重设连接日志。 cscf 将指向匹配到的 server 级别的核心配置 (即虚拟主机对应的 ngx_http_core_srv_conf_t), 这是函数最终要确定并赋予请求的配置对象。
条件编译: 若定义了宏 NGX_SUPPRESS_WARN(用于抑制某些编译器“可能未初始化”的警告), 则将 cscf 初始化为 NULL。 这只影响编译警告,对运行时逻辑无实际影响, 因为所有可达路径都会给 cscf 赋值。
将请求中的 HTTP 连接对象指针赋值给 hc, 方便后续访问 hc->addr_conf、hc->ssl_servername 等字段。

2 SSL 快速匹配路径
#if(NGX_HTTP_SSL&&defined SSL_CTRL_SET_TLSEXT_HOSTNAME)if(hc->ssl_servername){if(hc->ssl_servername->len==host->len&&ngx_strncmp(hc->ssl_servername->data,host->data,host->len)==0){#if(NGX_PCRE)if(hc->ssl_servername_regex&&ngx_http_regex_exec(r,hc->ssl_servername_regex,hc->ssl_servername)!=NGX_OK){ngx_http_close_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_ERROR;}#endifreturnNGX_OK;}}#endif
条件编译开始: 仅当 Nginx 编译时包含 SSL 模块, 并且 OpenSSL 库支持 SSL_CTRL_SET_TLSEXT_HOSTNAME(即 SNI 扩展)时, 才编译 SNI 相关代码块。

3 查找虚拟主机
rc=ngx_http_find_virtual_server(r->connection,hc->addr_conf->virtual_names,host,r,&cscf);
调用核心函数 ngx_http_find_virtual_server 执行真正的虚拟主机查找 参数1 r->connection:底层网络连接。 参数2 hc->addr_conf->virtual_names: 监听地址(addr_conf)下的所有虚拟主机名集合(包含精确名、前置通配、后置通配、正则表达式等)。 参数3 host:请求的 Host 头内容。 参数4 r:请求对象,可能用于日志或上下文。 参数5 &cscf:输出参数, 若找到匹配,则将对应的 ngx_http_core_srv_conf_t 指针写入此处。 返回值 rc 表示查找结果: NGX_OK:成功找到匹配的虚拟主机。 NGX_DECLINED:未找到任何匹配。 NGX_ERROR:查找过程出错(如正则匹配异常)。

4 错误检查
if(rc==NGX_ERROR){ngx_http_close_request(r,NGX_HTTP_INTERNAL_SERVER_ERROR);returnNGX_ERROR;}
如果查找过程发生错误, 以 500 内部服务器错误结束请求, 并返回 NGX_ERROR 给上层, 通知其停止进一步处理。

5 SSL 处理
#if(NGX_HTTP_SSL&&defined SSL_CTRL_SET_TLSEXT_HOSTNAME)if(hc->ssl_servername){ngx_http_ssl_srv_conf_t*sscf;if(rc==NGX_DECLINED){cscf=hc->addr_conf->default_server;rc=NGX_OK;}sscf=ngx_http_get_module_srv_conf(cscf->ctx,ngx_http_ssl_module);if(sscf->verify){ngx_log_error(NGX_LOG_INFO,r->connection->log,0,"client attempted to request the server name ""different from the one that was negotiated");ngx_http_finalize_request(r,NGX_HTTP_MISDIRECTED_REQUEST);returnNGX_ERROR;}}#endif
SSL 场景下匹配失败的补救及主机名验证

6 未匹配
if(rc==NGX_DECLINED){returnNGX_OK;}
未找到匹配 返回成功 意味着请求将继续使用之前已设置的 server 配置 (通常是在收到请求前根据 IP/端口选定的默认 server)

7 更新请求的配置
r->srv_conf=cscf->ctx->srv_conf;r->loc_conf=cscf->ctx->loc_conf;
找到了匹配的虚拟主机 将请求对象的模块配置指针切换到新选定的 server 块

clcf=ngx_http_get_module_loc_conf(r,ngx_http_core_module);ngx_set_connection_log(r->connection,clcf->error_log);
获取新选定 server(及当前 location 上下文)下 核心模块的 location 级配置,其中包含 error_log 等设置。 更新底层连接的日志对象 这样后续日志会输出到正确的地方, 并遵循该虚拟主机定义的日志级别

8 返回 成功
returnNGX_OK;}
http://www.cnnetsun.cn/news/2519448.html

相关文章:

  • 当自动化运维系统被ai重构后
  • 全开源CRM客户关系管理系统源码完整部署指南附代码
  • RK3588下位机程序无响应问题排查
  • 微信小程序 智能停车场预约推荐系统
  • 嵌入式Linux开发:GDB远程调试ARM平台的完整实战指南
  • AI开发基础(第9篇):Harness Engineering与知识地图
  • 写给新手的 release-management:昇腾版本管理到底是啥?
  • AI Agent Harness Engineering 的安全性挑战:提示词注入与防御
  • RK3568核心板开发全攻略:从硬件选型到量产落地的嵌入式实战指南
  • 内存核心频率停滞20年:从等效频率到延迟优化的性能真相
  • MCU+MPU双核架构在电力终端的设计:实时控制与智能计算的协同
  • RZ/T2H单芯多轴驱控一体方案:工业机器人实时控制与工业以太网集成
  • Office技巧速成:3个让效率翻倍的实用方法
  • eTs实战:从零构建猜大小游戏,掌握状态管理与事件绑定
  • Go语言实现DCI架构:用角色扮演解耦对象行为与数据
  • TranslucentTB:让Windows任务栏变身透明艺术品的完整指南
  • 同城中高端软体家具哪个品牌好
  • 2026年AI漫剧创作全链路培训测评:广东地区五家机构哪家更值得选?
  • Habitat具身智能仿真平台完全入门:从Sim到Lab,从环境搭建到配置详解
  • 从OpenAPI 3.1规范到实时交互式文档:ChatGPT驱动的API文档生成闭环体系(含性能压测数据对比)
  • Vibe Coding 工具怎么选?实测证明Trae才是Vibe Coding首选工具
  • Rust宏编程详解:从声明式到过程宏的完整指南
  • 程序员如何平衡工作与生活?我的“时间块”管理法
  • 《墨香情》手游官网入口:限时BOSS攻略,蹲点打法与掉落福利解析
  • 不只是写文案:AI创作工具的“全链路”能力正在成为新标准
  • 智能供应链革命——AI重塑泳装产业全链路
  • 实测百度网盘提速:从pandownload老玩家的视角,聊聊百度网盘不限速下载与解析的那些事
  • 新人还要绑定微信?
  • FlashAttention:让大模型训练快三倍的“拼菜师傅“
  • 因果本是叙事