直接用 httputil.NewSingleHostReverseProxy 是最安全的起点,它自动处理 hop-by-hop 头清理、连接复用和响应流透传;自己拼 http.NewRequest + http.Client.Do 或手动调用 req.Write() 容易漏掉 Host 同步、Body 重复读、TLS 上下文丢失等问题,90% 的 502/400 都源于绕过它。

直接用 httputil.NewSingleHostReverseProxy 是最安全的起点,它自动处理 hop-by-hop 头清理、连接复用和响应流透传;自己拼 http.NewRequest + http.Client.Do 或手动调用 req.Write() 容易漏掉 Host 同步、Body 重复读、TLS 上下文丢失等问题,90% 的 502/400 都源于绕过它。
为什么不能用 http.DefaultClient.Do 转发原始 *http.Request
很多人在 Handler 里直接把入参 *http.Request 改个 URL 就丢给 http.DefaultClient.Do(),结果后端收不到 Host、Body panic、查询参数消失、甚至 TLS 握手失败。
-
http.Request是服务端解析后的结构体,不是可重放的字节流;Do()会忽略req.URL.Host,强制从 URL 重建 Host 头 -
req.Body在服务端已被读取一次(如被http.MaxBytesReader或中间件消费),再读就 EOF 或 panic - 原始
RemoteAddr、HTTP/2 语义、100-continue 等上下文全丢失,后端无法做真实 IP 判断或流控 - 连接池不复用:每个请求新建 TCP 连接,容易耗尽文件描述符
Director 必须改哪三个字段
proxy.Director 是唯一安全修改请求的地方。漏改或错改会导致后端 404、协议降级、vhost 匹配失败。
-
req.URL.Scheme = backendURL.Scheme—— 否则默认沿用客户端请求的 scheme(比如客户端走 HTTPS,但后端只支持 HTTP) -
req.URL.Host = backendURL.Host—— 否则 Host 头仍是客户端域名,后端无法路由 -
req.Host = backendURL.Host—— HTTP/1.1 强制要求,req.URL.Host不会自动同步到该字段
额外建议:req.URL.Path 和 req.URL.RawPath 应保持同步(尤其含中文或特殊字符时),否则后端可能 decode 错误。
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
如何安全支持 CONNECT 方法(HTTPS 代理)
浏览器访问 HTTPS 站点前会先发 CONNECT google.com:443,此时不能走 HTTP 响应流程,必须升级为 TCP 隧道。
- 必须用
w.(http.Hijacker).Hijack()拿到底层net.Conn,否则无法接管原始字节流 - 连后端要用
net.Dial("tcp", r.Host),不是http.Get;若目标是:443,需自行处理 TLS(如用tls.Dial并传 SNI) -
io.Copy双向转发时,务必关闭连接超时:conn.SetDeadline(time.Time{}),否则拷贝中途会被中断 - 任一方向
io.Copy返回错误后,必须显式close()两端连接,否则泄漏
ModifyResponse 中容易踩的坑
proxy.ModifyResponse 用于改响应头或 body,但它的执行时机在响应 headers 已写入、body 开始流式传输之后。
- 不能在其中调用
w.WriteHeader()—— 此时已写过状态行,会 panic - 如果要修改 body(如注入 JS),必须先
io.ReadAll(resp.Body),再构造新bytes.Reader,否则流式响应被破坏 - 跨域头如
Access-Control-Allow-Origin可加,但注意:若后端本身返回了Vary: Origin,而你硬设*,可能引发缓存污染 - 不要在 ModifyResponse 里做耗时操作(如远程鉴权),它阻塞整个响应流
真正难的不是转发,而是判断哪些头该透传、哪些该重写、哪些该删——比如 Connection、Keep-Alive、Proxy-Authenticate 这类 hop-by-hop 头,httputil 不自动过滤,必须在 Director 里手动删。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










