From 085df25c7e82b5bdd198787232d559f2ac1e72eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 9 Aug 2022 18:53:24 +0200 Subject: [PATCH] reverseproxy: Support 1xx status codes (HTTP early hints) (#4882) --- .../caddyhttp/reverseproxy/reverseproxy.go | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index 8887511e..276616b4 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -23,9 +23,11 @@ import ( "io" "net" "net/http" + "net/http/httptrace" "net/textproto" "net/url" "regexp" + "runtime" "strconv" "strings" "sync" @@ -40,7 +42,11 @@ import ( "golang.org/x/net/http/httpguts" ) +var supports1xx bool + func init() { + supports1xx = !regexp.MustCompile(`^go1\.1(?:7|8)\.`).Match([]byte(runtime.Version())) + caddy.RegisterModule(Handler{}) } @@ -732,6 +738,25 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe server := req.Context().Value(caddyhttp.ServerCtxKey).(*caddyhttp.Server) shouldLogCredentials := server.Logs != nil && server.Logs.ShouldLogCredentials + if supports1xx { + // Forward 1xx status codes, backported from https://github.com/golang/go/pull/53164 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + h := rw.Header() + copyHeader(h, http.Header(header)) + rw.WriteHeader(code) + + // Clear headers, it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses + for k := range h { + delete(h, k) + } + + return nil + }, + } + req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) + } + // do the round-trip; emit debug log with values we know are // safe, or if there is no error, emit fuller log entry start := time.Now()