MCPcopy
hub / github.com/caddyserver/caddy / reverseProxy

Method reverseProxy

modules/caddyhttp/reverseproxy/reverseproxy.go:990–1207  ·  modules/caddyhttp/reverseproxy/reverseproxy.go::Handler.reverseProxy

reverseProxy performs a round-trip to the given backend and processes the response with the client. (This method is mostly the beginning of what was borrowed from the net/http/httputil package in the Go standard library which was used as the foundation.)

(rw http.ResponseWriter, req *http.Request, origReq *http.Request, repl *caddy.Replacer, di DialInfo, next caddyhttp.Handler)

Source from the content-addressed store, hash-verified

988// (This method is mostly the beginning of what was borrowed from the net/http/httputil package in the
989// Go standard library which was used as the foundation.)
990func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, origReq *http.Request, repl *caddy.Replacer, di DialInfo, next caddyhttp.Handler) error {
991 _ = di.Upstream.Host.countRequest(1)
992
993 // Increment the in-flight request count
994 incInFlightRequest(di.Address)
995
996 //nolint:errcheck
997 defer func() {
998 di.Upstream.Host.countRequest(-1)
999 // Decrement the in-flight request count
1000 decInFlightRequest(di.Address)
1001 }()
1002
1003 // point the request to this upstream
1004 h.directRequest(req, di)
1005
1006 server := req.Context().Value(caddyhttp.ServerCtxKey).(*caddyhttp.Server)
1007 shouldLogCredentials := server.Logs != nil && server.Logs.ShouldLogCredentials
1008
1009 // Forward 1xx status codes, backported from https://github.com/golang/go/pull/53164
1010 var (
1011 roundTripMutex sync.Mutex
1012 roundTripDone bool
1013 )
1014 trace := &httptrace.ClientTrace{
1015 Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
1016 roundTripMutex.Lock()
1017 defer roundTripMutex.Unlock()
1018 if roundTripDone {
1019 // If RoundTrip has returned, don't try to further modify
1020 // the ResponseWriter's header map.
1021 return nil
1022 }
1023 h := rw.Header()
1024 copyHeader(h, http.Header(header))
1025 rw.WriteHeader(code)
1026
1027 // Clear headers coming from the backend
1028 // (it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses)
1029 clear(h)
1030
1031 return nil
1032 },
1033 }
1034 req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
1035
1036 // do the round-trip
1037 start := time.Now()
1038 res, err := h.Transport.RoundTrip(req)
1039 duration := time.Since(start)
1040
1041 // record that the round trip is done for the 1xx response handler
1042 roundTripMutex.Lock()
1043 roundTripDone = true
1044 roundTripMutex.Unlock()
1045
1046 // emit debug log with values we know are safe,
1047 // or if there is no error, emit fuller log entry

Callers 1

proxyLoopIterationMethod · 0.95

Calls 15

directRequestMethod · 0.95
countFailureMethod · 0.95
bufferedBodyMethod · 0.95
finalizeResponseMethod · 0.95
StatusCodeMatchesFunction · 0.92
ErrorFunction · 0.92
incInFlightRequestFunction · 0.85
decInFlightRequestFunction · 0.85
copyHeaderFunction · 0.85
countRequestMethod · 0.80
DurationMethod · 0.80

Tested by

no test coverage detected