diff --git a/caddytest/integration/caddyfile_adapt/forward_auth_rename_headers.txt b/caddytest/integration/caddyfile_adapt/forward_auth_rename_headers.txt new file mode 100644 index 00000000..bc2d95b9 --- /dev/null +++ b/caddytest/integration/caddyfile_adapt/forward_auth_rename_headers.txt @@ -0,0 +1,116 @@ +:8881 + +forward_auth localhost:9000 { + uri /auth + copy_headers A>1 B C>3 { + D + E>5 + } +} +---------- +{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":8881" + ], + "routes": [ + { + "handle": [ + { + "handle_response": [ + { + "match": { + "status_code": [ + 2 + ] + }, + "routes": [ + { + "handle": [ + { + "handler": "headers", + "request": { + "set": { + "1": [ + "{http.reverse_proxy.header.A}" + ], + "3": [ + "{http.reverse_proxy.header.C}" + ], + "5": [ + "{http.reverse_proxy.header.E}" + ], + "B": [ + "{http.reverse_proxy.header.B}" + ], + "D": [ + "{http.reverse_proxy.header.D}" + ] + } + } + } + ] + } + ] + }, + { + "routes": [ + { + "handle": [ + { + "exclude": [ + "Connection", + "Keep-Alive", + "Te", + "Trailers", + "Transfer-Encoding", + "Upgrade" + ], + "handler": "copy_response_headers" + } + ] + }, + { + "handle": [ + { + "handler": "copy_response" + } + ] + } + ] + } + ], + "handler": "reverse_proxy", + "headers": { + "request": { + "set": { + "X-Forwarded-Method": [ + "{http.request.method}" + ], + "X-Forwarded-Uri": [ + "{http.request.uri}" + ] + } + } + }, + "rewrite": { + "method": "GET", + "uri": "/auth" + }, + "upstreams": [ + { + "dial": "localhost:9000" + } + ] + } + ] + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go b/modules/caddyhttp/reverseproxy/forwardauth/caddyfile.go index 1571f09a..c22dddec 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" + "strings" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/caddyconfig" @@ -115,7 +116,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) // collect the headers to copy from the auth response // onto the original request, so they can get passed // through to a backend app - headersToCopy := []string{} + headersToCopy := make(map[string]string) // read the subdirectives for configuring the forward_auth shortcut // NOTE: we delete the tokens as we go so that the reverse_proxy @@ -141,10 +142,28 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) case "copy_headers": args := dispenser.RemainingArgs() - dispenser.Delete() - for _, headerField := range args { + hadBlock := false + for nesting := dispenser.Nesting(); dispenser.NextBlock(nesting); { + hadBlock = true + args = append(args, dispenser.Val()) + } + + dispenser.Delete() // directive name + if hadBlock { + dispenser.Delete() // opening brace + dispenser.Delete() // closing brace + } + for range args { dispenser.Delete() - headersToCopy = append(headersToCopy, headerField) + } + + for _, headerField := range args { + if strings.Contains(headerField, ">") { + parts := strings.Split(headerField, ">") + headersToCopy[parts[0]] = parts[1] + } else { + headersToCopy[headerField] = headerField + } } if len(headersToCopy) == 0 { return nil, dispenser.ArgErr() @@ -180,9 +199,9 @@ func parseCaddyfile(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) }, } - for _, headerField := range headersToCopy { - handler.Request.Set[headerField] = []string{ - "{http.reverse_proxy.header." + headerField + "}", + for from, to := range headersToCopy { + handler.Request.Set[to] = []string{ + "{http.reverse_proxy.header." + from + "}", } }