@marcel91200 / caddy Mirror · read-only / commits / aef8d4de
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

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

Francis Lavoie committed May 12, 2021 at 16:19 UTC aef8d4decceba3371d6722a81e17cd5f94162116
1 file changed +12 -3
modules/caddyhttp/reverseproxy/reverseproxy.go
+12 -3
@@ -120,9 +120,10 @@ type Handler struct {
120 // handler chain will not affect the health status of the
121 // backend.
122 //
123 - // Two new placeholders are available in this handler chain:
124 - // - `{http.reverse_proxy.status_code}` The status code
125 - // - `{http.reverse_proxy.status_text}` The status text
123 + // Three new placeholders are available in this handler chain:
124 + // - `{http.reverse_proxy.status_code}` The status code from the response
125 + // - `{http.reverse_proxy.status_text}` The status text from the response
126 + // - `{http.reverse_proxy.header.*}` The headers from the response
127 HandleResponse []caddyhttp.ResponseHandler `json:"handle_response,omitempty"`
128
129 Transport http.RoundTripper `json:"-"`
@@ -631,9 +632,17 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, repl *
632 if len(rh.Routes) == 0 {
633 continue
634 }
635 +
636 res.Body.Close()
637 +
638 + // set up the replacer so that parts of the original response can be
639 + // used for routing decisions
640 + for field, value := range res.Header {
641 + repl.Set("http.reverse_proxy.header."+field, strings.Join(value, ","))
642 + }
643 repl.Set("http.reverse_proxy.status_code", res.StatusCode)
644 repl.Set("http.reverse_proxy.status_text", res.Status)
645 +
646 h.logger.Debug("handling response", zap.Int("handler", i))
647 if routeErr := rh.Routes.Compile(next).ServeHTTP(rw, req); routeErr != nil {
648 // wrap error in roundtripSucceeded so caller knows that