From b30b979f05a23671ffaaaa70eff448c392311dd9 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 12 May 2021 00:25:09 -0400 Subject: [PATCH] reverseproxy: Set the headers in the replacer before `handle_response` Turns out this was an oversight, we assumed we could use `{http.response.header.*}` but that doesn't work because those are grabbed from the response writer, and we haven't copied any headers into the response writer yet. So the fix is to set all the response headers into the replacer at a new namespace before running the handlers. This adds the `{http.reverse_proxy.header.*}` replacer. See https://caddy.community/t/empty-http-response-header-x-accel-redirect/12447 --- modules/caddyhttp/reverseproxy/reverseproxy.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index ddb3ca9295f..671f42a28e6 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -120,9 +120,10 @@ type Handler struct { // handler chain will not affect the health status of the // backend. // - // Two new placeholders are available in this handler chain: - // - `{http.reverse_proxy.status_code}` The status code - // - `{http.reverse_proxy.status_text}` The status text + // Three new placeholders are available in this handler chain: + // - `{http.reverse_proxy.status_code}` The status code from the response + // - `{http.reverse_proxy.status_text}` The status text from the response + // - `{http.reverse_proxy.header.*}` The headers from the response HandleResponse []caddyhttp.ResponseHandler `json:"handle_response,omitempty"` Transport http.RoundTripper `json:"-"` @@ -631,9 +632,17 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, repl * if len(rh.Routes) == 0 { continue } + res.Body.Close() + + // set up the replacer so that parts of the original response can be + // used for routing decisions + for field, value := range res.Header { + repl.Set("http.reverse_proxy.header."+field, strings.Join(value, ",")) + } repl.Set("http.reverse_proxy.status_code", res.StatusCode) repl.Set("http.reverse_proxy.status_text", res.Status) + h.logger.Debug("handling response", zap.Int("handler", i)) if routeErr := rh.Routes.Compile(next).ServeHTTP(rw, req); routeErr != nil { // wrap error in roundtripSucceeded so caller knows that