summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancis Lavoie <lavofr@gmail.com>2021-05-12 16:19:08 -0400
committerGitHub <noreply@github.com>2021-05-12 14:19:08 -0600
commitaef8d4decceba3371d6722a81e17cd5f94162116 (patch)
tree73de0d6094ef00dab99e26c4bef997605685e491
parent37718560c1bf8e330d18edb2e663e64a624dee8e (diff)
reverseproxy: Set the headers in the replacer before `handle_response` (#4165)
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
-rw-r--r--modules/caddyhttp/reverseproxy/reverseproxy.go15
1 files changed, 12 insertions, 3 deletions
diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go
index ddb3ca9..671f42a 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