@@ -807,17 +807,26 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe
807
807
shouldLogCredentials := server .Logs != nil && server .Logs .ShouldLogCredentials
808
808
809
809
// Forward 1xx status codes, backported from https://github.com/golang/go/pull/53164
810
+ var (
811
+ roundTripMutex sync.Mutex
812
+ roundTripDone bool
813
+ )
810
814
trace := & httptrace.ClientTrace {
811
815
Got1xxResponse : func (code int , header textproto.MIMEHeader ) error {
816
+ roundTripMutex .Lock ()
817
+ defer roundTripMutex .Unlock ()
818
+ if roundTripDone {
819
+ // If RoundTrip has returned, don't try to further modify
820
+ // the ResponseWriter's header map.
821
+ return nil
822
+ }
812
823
h := rw .Header ()
813
824
copyHeader (h , http .Header (header ))
814
825
rw .WriteHeader (code )
815
826
816
827
// Clear headers coming from the backend
817
828
// (it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses)
818
- for k := range header {
819
- delete (h , k )
820
- }
829
+ clear (h )
821
830
822
831
return nil
823
832
},
@@ -833,11 +842,18 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origRe
833
842
req = req .WithContext (context .WithoutCancel (req .Context ()))
834
843
}
835
844
836
- // do the round-trip; emit debug log with values we know are
837
- // safe, or if there is no error, emit fuller log entry
845
+ // do the round-trip
838
846
start := time .Now ()
839
847
res , err := h .Transport .RoundTrip (req )
840
848
duration := time .Since (start )
849
+
850
+ // record that the round trip is done for the 1xx response handler
851
+ roundTripMutex .Lock ()
852
+ roundTripDone = true
853
+ roundTripMutex .Unlock ()
854
+
855
+ // emit debug log with values we know are safe,
856
+ // or if there is no error, emit fuller log entry
841
857
logger := h .logger .With (
842
858
zap .String ("upstream" , di .Upstream .String ()),
843
859
zap .Duration ("duration" , duration ),
0 commit comments