配 host 和 URL 替换是在开发中比较常用的两种规则,这两种规则某些情况下功能相似容易搞混,如:
1. ke.qq.com 10.1.2.3:8080
2. ke.qq.com/user 10.1.2.3:8080
3. ke.qq.com 10.1.2.3:8080/
4. ke.qq.com //10.1.2.3:8080
5. ke.qq.com http://10.1.2.3:8080
6. ke.qq.com/user http://10.1.2.3:8080
上述常见配置功能看起来差不多,都是把指定请求转到 10.1.2.3:8080,但结果大不相同,里面不仅包含 host 配置(1、2行,形如 pattern ip[:port] 或 pattern host://domain[:port] 的配置,端口可选)及 URL 替换(3~6行)两种规则,且 URL 替换里面也有一些差异,了解上述配置的差异之前,我们先看下客户端请求经过 whistle 再到 server 的处理过程:

请求到 whistle 后,先解析用户配置的规则,根据匹配规则判断请求是否转发到远程服务器,如果请求要转到远程服务器,则配置 host 和 URL 替换的后续流程分别如下:
配 host
如果只是配置 host,whistle 会根据请求 URL 解析 host 规则获取服务器的 IP 和端口,并和该 IP 和端口建立 TCP 连接后(如果是 https 则建立 TLS 连接),将请求数据通过此连接原封不动转发出去,即客户端发送什么 URL,后台就收到什么 URL。

URL 替换
如果是 URL 替换,whistle 会根据配置解析组装新的 URL ,如:
ke.qq.com/user http://10.1.2.3:8080

如果匹配的 URL 里面没有带 http 或 https 协议,则表示跟原请求协议一致
所有 ke.qq.com/user 及 ke.qq.com/user/path/to 的请求都会匹配上述规则,并自动补齐路径生成新的 URL :http://10.1.2.3:8080/path/to,whistle 再根据新的 URL 解析出 server 的 IP 和 端口(获取路径:whistle 配置 > 系统Hosts > 远程 DNS 获取),并和该 IP 和端口(10.1.2.3 + 8080)建立 TCP 连接后(如果新 URL 是 https 则建立 TLS 连接),修改请求数据:
- 原请求
GET /user/path/to HTTP/1.1 Host: ke.qq.com ...... - 修改后
GET /path/to HTTP/1.1 Host: 10.1.2.3:8080 ......
路径和域名都被替换掉
将修改后的请求数据通过刚才建立的 TCP 连接发送出去,即客户端请求 https://ke.qq.com/user/path/to?xxx 通过 URL 替换后,后台收到的请求 URL 为 http://10.1.2.3:8080/path/to?xxx。
总之,host 只是将请求转发到指定的 IP + 端口,而 URL 替换在此基础上还会修改 请求域名 + 路径。