reverse_proxy: use http1 for outbound tls requests with placeholder that are likely websockets (#7296)

This commit is contained in:
WeidiDeng 2025-10-10 00:36:49 +08:00 committed by GitHub
parent 178294e9d7
commit 2ec28bca43
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 0 deletions

View file

@ -281,3 +281,7 @@ const proxyProtocolInfoVarKey = "reverse_proxy.proxy_protocol_info"
type ProxyProtocolInfo struct { type ProxyProtocolInfo struct {
AddrPort netip.AddrPort AddrPort netip.AddrPort
} }
// tlsH1OnlyVarKey is the key used that indicates the connection will use h1 only for TLS.
// https://github.com/caddyserver/caddy/issues/7292
const tlsH1OnlyVarKey = "reverse_proxy.tls_h1_only"

View file

@ -409,6 +409,14 @@ func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, e
repl := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer) repl := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
tlsConfig := rt.TLSClientConfig.Clone() tlsConfig := rt.TLSClientConfig.Clone()
tlsConfig.ServerName = repl.ReplaceAll(tlsConfig.ServerName, "") tlsConfig.ServerName = repl.ReplaceAll(tlsConfig.ServerName, "")
// h1 only
if caddyhttp.GetVar(ctx, tlsH1OnlyVarKey) == true {
// stdlib does this
// https://github.com/golang/go/blob/4837fbe4145cd47b43eed66fee9eed9c2b988316/src/net/http/transport.go#L1701
tlsConfig.NextProtos = nil
}
tlsConn := tls.Client(conn, tlsConfig) tlsConn := tls.Client(conn, tlsConfig)
// complete the handshake before returning the connection // complete the handshake before returning the connection

View file

@ -726,6 +726,12 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.
proxyProtocolInfo := ProxyProtocolInfo{AddrPort: addrPort} proxyProtocolInfo := ProxyProtocolInfo{AddrPort: addrPort}
caddyhttp.SetVar(req.Context(), proxyProtocolInfoVarKey, proxyProtocolInfo) caddyhttp.SetVar(req.Context(), proxyProtocolInfoVarKey, proxyProtocolInfo)
// some of the outbound requests require h1 (e.g. websocket)
// https://github.com/golang/go/blob/4837fbe4145cd47b43eed66fee9eed9c2b988316/src/net/http/request.go#L1579
if isWebsocket(req) {
caddyhttp.SetVar(req.Context(), tlsH1OnlyVarKey, true)
}
// Add the supported X-Forwarded-* headers // Add the supported X-Forwarded-* headers
err = h.addForwardedHeaders(req) err = h.addForwardedHeaders(req)
if err != nil { if err != nil {