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

httpclient与hertzclient在处理Host header时的差别

本文中的Host header、request.header.host、req.Header[“Host”]都指的是请求头中的“Host”字段。

问题提出

在请求转发的过程中,需要从原请求中拿到一些信息来构造新的转发出去的请求,其中就有Host header的问题。一开始我使用的是httpclient,复制请求头的逻辑就是清除一些字段后直接全部复制过去(Host header不在清除范围内),此时程序正常运行。

	c.Request.Header.VisitAll(func(key, value []byte) {req.Header.Add(string(key), string(value))})

当我将httpclient切换成hertzclient后,发现一模一样的复制请求头的逻辑遇到了404的错误。经过一番排查发现是httpclient和hertzclient两者对于request.header.host的处理方式不同。对于hertzclient来说,正确的方式应该是不复制请求头中的Host字段。

	c.Request.Header.VisitAll(func(key, value []byte) {if string(key) != "Host" {	  // hertz框架中的client不会更改header.Host,所以不能用原来的Hostreq.Header.Add(string(key), string(value))}})

httpclient

httpclient请求最终发送的 Host header 并不是取自 req.Header[“Host”],而是由 req.Host 字段决定,如果 req.Host 为空,则默认为 req.URL.Host。

所以说虽然我一开始直接把原始的、错误的 Host header 复制了过去,但是httpclient对请求的 Host header 进行了替换,没有用我设置的 Host header ,所以并没有出现问题。

hertzclient

hertzclient最后发送的 Host header 就是取自 req.Header[“Host”] 的,所以说当我将原来的 request.header.host 写到新请求中后,hertzclient发送请求直接使用的是我设置的 Host header ,所以出现404的问题。

如果说依然使用完整复制的方法,在最后需要用req.Header.SetHost()替换原始的、错误的 Host header 。注意不是req.SetHost(),这个方法是设置建立连接的主机地址。

Host header作用

那话说回来,为什么使用错误的Host header会出现404的问题呢?Host header究竟是起到什么样的作用呢?

当一个网络请求发出去之后,网址会经过DNS解析为ip地址并建立连接,当连接到服务器后,则会用到 Host header 进行虚拟主机分流。

而虚拟主机(Virtual Host)是一种服务器技术,它允许在同一台物理服务器(同一个IP地址)上运行多个网站。换句话说,你可以用一台服务器托管多个不同域名的网站,而不需要每个网站都分配一个独立的服务器。区分用户到底访问的是哪个网站的方式就是使用 Host header 进行分流。

总体来说,一个请求的流程是:域名 → DNS 解析 → IP 地址 → 建立 TCP/SSL 连接 → 发送 HTTP 请求头 (Host) → 虚拟主机分流。

这里举一个Nginx配置规则进行分流的例子:

server {listen 80;server_name www.example.com;root /var/www/example;
}server {listen 80;server_name www.test.com;root /var/www/test;
}
  • listen 80; → 表示监听 HTTP 默认端口 80
  • server_name → 表示这个虚拟主机匹配的域名。
  • root → 表示网站的根目录,也就是请求 / 时返回的文件位置。

Nginx 的分流步骤可以总结为:

  1. 根据端口匹配 server 块
    • 这里两个 server 都监听 80,所以都在候选列表中。
  2. 根据 Host 匹配 server_name
    • Nginx 会查找与请求 Host 最匹配的 server 块。
  3. 匹配成功 → 使用该 server 块的 root 和配置处理请求
  4. 没有匹配 → 使用默认 server
    • Nginx 会选择 listen 指令中第一个或 default_server 标记的 server 作为默认返回。
http://www.xdnf.cn/news/1344781.html

相关文章:

  • 【GPT入门】第53课 LlamaFactory微调效果与vllm部署效果不一致问题解决
  • open webui源码分析6-Function
  • FPGA学习笔记——简单的IIC读写EEPROM
  • FPGA高端项目:图像采集+Aurora 8B10B+UDP图传架构,基于GTH高速收发器的光口转网口,提供工程源码和技术支持
  • IntelliJ IDEA 常用快捷键笔记(Windows)
  • SRE系列(二) | 从可用性到 SLI/SLO
  • 【数据结构】B 树——高度近似可”独木成林“的榕树——详细解说与其 C 代码实现
  • MySQL编程开发(了解)
  • 08高级语言逻辑结构到汇编语言之逻辑结构转换 continue break 完结汇编按逻辑结构
  • Redis---事务
  • 51单片机-驱动步进电机模块教程
  • C#_组合优于继承的实际应用
  • Kafka Broker 核心原理全解析:存储、高可用与数据同步
  • 如何从根源上理解并解决前端的CORS跨域问题
  • 【PSINS工具箱】MATLAB例程,二维平面上的组合导航,EKF融合速度、位置和IMU数据,4维观测量
  • Unreal Engine ClassName Rule
  • Python 中 SQLAlchemy 和 MySQLdb 的关系
  • IKE 与 ISAKMP 核心笔记
  • 微信扫码登陆 —— 接收消息
  • 复合设计模式
  • 加密货币与区块链:六大刑事重灾区
  • 深入理解 Spring Boot Starter:简化依赖管理与自动配置的利器
  • 110、【OS】【Nuttx】【周边】效果呈现方案解析:查找最新构建件
  • 深入理解 hash -r:解决 Linux 命令缓存难题的关键密钥
  • 自定义rabbitmq的ConnectionFactory配置
  • RabbitMQ深度剖析:从基础到高级进阶实战
  • 乐迪信息:AI摄像机+刮板机人员入侵检测:杜绝井下安全事故
  • 爬虫基础学习-配置代理、以及项目实践
  • 关于爬虫的基本步骤说明【爬虫七步骤】
  • jenkins实现分布式构建并自动发布到远程服务器上 jenkins实现自动打包编译发布远程服务器