Skip to content

Commit

Permalink
reverseproxy: Sync changes from stdlib for 1xx handling (#6656)
Browse files Browse the repository at this point in the history
* reverseproxy: Sync changes from stdlib for 1xx handling

Sourced from golang/go@960654b

* Use clear()

golang/go@3bc2840
  • Loading branch information
francislavoie authored Oct 22, 2024
1 parent 5e6024c commit fbf0f4c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
4 changes: 1 addition & 3 deletions modules/caddyhttp/headers/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,7 @@ func (ops HeaderOps) ApplyTo(hdr http.Header, repl *caddy.Replacer) {
for _, fieldName := range ops.Delete {
fieldName = repl.ReplaceKnown(fieldName, "")
if fieldName == "*" {
for existingField := range hdr {
delete(hdr, existingField)
}
clear(hdr)
}
}

Expand Down
26 changes: 21 additions & 5 deletions modules/caddyhttp/reverseproxy/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -807,17 +807,26 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe
shouldLogCredentials := server.Logs != nil && server.Logs.ShouldLogCredentials

// Forward 1xx status codes, backported from https://github.com/golang/go/pull/53164
var (
roundTripMutex sync.Mutex
roundTripDone bool
)
trace := &httptrace.ClientTrace{
Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
roundTripMutex.Lock()
defer roundTripMutex.Unlock()
if roundTripDone {
// If RoundTrip has returned, don't try to further modify
// the ResponseWriter's header map.
return nil
}
h := rw.Header()
copyHeader(h, http.Header(header))
rw.WriteHeader(code)

// Clear headers coming from the backend
// (it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses)
for k := range header {
delete(h, k)
}
clear(h)

return nil
},
Expand All @@ -833,11 +842,18 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe
req = req.WithContext(context.WithoutCancel(req.Context()))
}

// do the round-trip; emit debug log with values we know are
// safe, or if there is no error, emit fuller log entry
// do the round-trip
start := time.Now()
res, err := h.Transport.RoundTrip(req)
duration := time.Since(start)

// record that the round trip is done for the 1xx response handler
roundTripMutex.Lock()
roundTripDone = true
roundTripMutex.Unlock()

// emit debug log with values we know are safe,
// or if there is no error, emit fuller log entry
logger := h.logger.With(
zap.String("upstream", di.Upstream.String()),
zap.Duration("duration", duration),
Expand Down

0 comments on commit fbf0f4c

Please sign in to comment.