aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/caddyhttp/reverseproxy/forwardauth
diff options
context:
space:
mode:
authorFrancis Lavoie <[email protected]>2024-11-04 16:58:53 -0500
committerGitHub <[email protected]>2024-11-04 14:58:53 -0700
commit05cfb121ec3f214c0e45206c188f34bad4d4eb8c (patch)
treecf8888b1c6d8f0a4ab81ca59384b352ecd9d6619 /modules/caddyhttp/reverseproxy/forwardauth
parent00f948c6056f6968b07e2b92d537c0a61559e2ed (diff)
downloadcaddy-05cfb121ec3f214c0e45206c188f34bad4d4eb8c.tar.gz
caddy-05cfb121ec3f214c0e45206c188f34bad4d4eb8c.zip
forwardauth: Skip copying missing response headers (#6608)
Diffstat (limited to 'modules/caddyhttp/reverseproxy/forwardauth')
-rw-r--r--modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go67
1 files changed, 46 insertions, 21 deletions
diff --git a/modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go b/modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go
index 8350096ae..347f6dfbf 100644
--- a/modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go
+++ b/modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go
@@ -17,6 +17,7 @@ package forwardauth
import (
"encoding/json"
"net/http"
+ "sort"
"strings"
"github.com/caddyserver/caddy/v2"
@@ -170,42 +171,66 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
return nil, dispenser.Errf("the 'uri' subdirective is required")
}
- // set up handler for good responses; when a response
- // has 2xx status, then we will copy some headers from
- // the response onto the original request, and allow
- // handling to continue down the middleware chain,
- // by _not_ executing a terminal handler.
+ // Set up handler for good responses; when a response has 2xx status,
+ // then we will copy some headers from the response onto the original
+ // request, and allow handling to continue down the middleware chain,
+ // by _not_ executing a terminal handler. We must have at least one
+ // route in the response handler, even if it's no-op, so that the
+ // response handling logic in reverse_proxy doesn't skip this entry.
goodResponseHandler := caddyhttp.ResponseHandler{
Match: &caddyhttp.ResponseMatcher{
StatusCode: []int{2},
},
- Routes: []caddyhttp.Route{},
- }
-
- handler := &headers.Handler{
- Request: &headers.HeaderOps{
- Set: http.Header{},
+ Routes: []caddyhttp.Route{
+ {
+ HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(
+ &caddyhttp.VarsMiddleware{},
+ "handler",
+ "vars",
+ nil,
+ )},
+ },
},
}
- // the list of headers to copy may be empty, but that's okay; we
- // need at least one handler in the routes for the response handling
- // logic in reverse_proxy to not skip this entry as empty.
- for from, to := range headersToCopy {
- handler.Request.Set.Set(to, "{http.reverse_proxy.header."+http.CanonicalHeaderKey(from)+"}")
+ // Sort the headers so that the order in the JSON output is deterministic.
+ sortedHeadersToCopy := make([]string, 0, len(headersToCopy))
+ for k := range headersToCopy {
+ sortedHeadersToCopy = append(sortedHeadersToCopy, k)
}
+ sort.Strings(sortedHeadersToCopy)
- goodResponseHandler.Routes = append(
- goodResponseHandler.Routes,
- caddyhttp.Route{
+ // Set up handlers to copy headers from the auth response onto the
+ // original request. We use vars matchers to test that the placeholder
+ // values aren't empty, because the header handler would not replace
+ // placeholders which have no value.
+ copyHeaderRoutes := []caddyhttp.Route{}
+ for _, from := range sortedHeadersToCopy {
+ to := http.CanonicalHeaderKey(headersToCopy[from])
+ placeholderName := "http.reverse_proxy.header." + http.CanonicalHeaderKey(from)
+ handler := &headers.Handler{
+ Request: &headers.HeaderOps{
+ Set: http.Header{
+ to: []string{"{" + placeholderName + "}"},
+ },
+ },
+ }
+ copyHeaderRoutes = append(copyHeaderRoutes, caddyhttp.Route{
+ MatcherSetsRaw: []caddy.ModuleMap{{
+ "not": h.JSON(caddyhttp.MatchNot{MatcherSetsRaw: []caddy.ModuleMap{{
+ "vars": h.JSON(caddyhttp.VarsMatcher{"{" + placeholderName + "}": []string{""}}),
+ }}}),
+ }},
HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(
handler,
"handler",
"headers",
nil,
)},
- },
- )
+ })
+ }
+
+ goodResponseHandler.Routes = append(goodResponseHandler.Routes, copyHeaderRoutes...)
// note that when a response has any other status than 2xx, then we
// use the reverse proxy's default behaviour of copying the response