Browse Source

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
master
Francis Lavoie 4 years ago
committed by GitHub
parent
commit
aef8d4decc
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      modules/caddyhttp/reverseproxy/reverseproxy.go

15
modules/caddyhttp/reverseproxy/reverseproxy.go

@ -120,9 +120,10 @@ type Handler struct {
// handler chain will not affect the health status of the // handler chain will not affect the health status of the
// backend. // backend.
// //
// Two new placeholders are available in this handler chain: // Three new placeholders are available in this handler chain:
// - `{http.reverse_proxy.status_code}` The status code // - `{http.reverse_proxy.status_code}` The status code from the response
// - `{http.reverse_proxy.status_text}` The status text // - `{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"` HandleResponse []caddyhttp.ResponseHandler `json:"handle_response,omitempty"`
Transport http.RoundTripper `json:"-"` Transport http.RoundTripper `json:"-"`
@ -631,9 +632,17 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, repl *
if len(rh.Routes) == 0 { if len(rh.Routes) == 0 {
continue continue
} }
res.Body.Close() 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_code", res.StatusCode)
repl.Set("http.reverse_proxy.status_text", res.Status) repl.Set("http.reverse_proxy.status_text", res.Status)
h.logger.Debug("handling response", zap.Int("handler", i)) h.logger.Debug("handling response", zap.Int("handler", i))
if routeErr := rh.Routes.Compile(next).ServeHTTP(rw, req); routeErr != nil { if routeErr := rh.Routes.Compile(next).ServeHTTP(rw, req); routeErr != nil {
// wrap error in roundtripSucceeded so caller knows that // wrap error in roundtripSucceeded so caller knows that

Loading…
Cancel
Save