From f6900fcf530e80c921dac8e4f09996cffce7f436 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Fri, 6 May 2022 10:50:26 -0400 Subject: reverseproxy: Support performing pre-check requests (#4739) --- caddyconfig/httpcaddyfile/builtins.go | 16 ++++++++++++++-- caddyconfig/httpcaddyfile/builtins_test.go | 21 ++++++++++++++++++--- caddyconfig/httpcaddyfile/directives.go | 1 + caddyconfig/httpcaddyfile/httptype.go | 1 + 4 files changed, 34 insertions(+), 5 deletions(-) (limited to 'caddyconfig/httpcaddyfile') diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go index 1e7c701..5c539e2 100644 --- a/caddyconfig/httpcaddyfile/builtins.go +++ b/caddyconfig/httpcaddyfile/builtins.go @@ -580,12 +580,24 @@ func parseRedir(h Helper) (caddyhttp.MiddlewareHandler, error) { body = fmt.Sprintf(metaRedir, safeTo, safeTo, safeTo, safeTo) code = "302" default: + // Allow placeholders for the code + if strings.HasPrefix(code, "{") { + break + } + // Try to validate as an integer otherwise codeInt, err := strconv.Atoi(code) if err != nil { return nil, h.Errf("Not a supported redir code type or not valid integer: '%s'", code) } - if codeInt < 300 || codeInt > 399 { - return nil, h.Errf("Redir code not in the 3xx range: '%v'", codeInt) + // Sometimes, a 401 with Location header is desirable because + // requests made with XHR will "eat" the 3xx redirect; so if + // the intent was to redirect to an auth page, a 3xx won't + // work. Responding with 401 allows JS code to read the + // Location header and do a window.location redirect manually. + // see https://stackoverflow.com/a/2573589/846934 + // see https://github.com/oauth2-proxy/oauth2-proxy/issues/1522 + if codeInt < 300 || (codeInt > 399 && codeInt != 401) { + return nil, h.Errf("Redir code not in the 3xx range or 401: '%v'", codeInt) } } diff --git a/caddyconfig/httpcaddyfile/builtins_test.go b/caddyconfig/httpcaddyfile/builtins_test.go index 991c649..bd5e116 100644 --- a/caddyconfig/httpcaddyfile/builtins_test.go +++ b/caddyconfig/httpcaddyfile/builtins_test.go @@ -149,20 +149,35 @@ func TestRedirDirectiveSyntax(t *testing.T) { expectError: false, }, { + // this is now allowed so a Location header + // can be written and consumed by JS + // in the case of XHR requests input: `:8080 { - redir /old.html /new.html htlm + redir * :8081 401 + }`, + expectError: false, + }, + { + input: `:8080 { + redir * :8081 402 }`, expectError: true, }, { input: `:8080 { - redir * :8081 200 + redir * :8081 {http.reverse_proxy.status_code} + }`, + expectError: false, + }, + { + input: `:8080 { + redir /old.html /new.html htlm }`, expectError: true, }, { input: `:8080 { - redir * :8081 400 + redir * :8081 200 }`, expectError: true, }, diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go index aaa8cb0..164b912 100644 --- a/caddyconfig/httpcaddyfile/directives.go +++ b/caddyconfig/httpcaddyfile/directives.go @@ -57,6 +57,7 @@ var directiveOrder = []string{ // middleware handlers; some wrap responses "basicauth", + "forward_auth", "request_header", "encode", "push", diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index 242f0b8..9c723db 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -130,6 +130,7 @@ func (st ServerType) Setup(inputServerBlocks []caddyfile.ServerBlock, {regexp.MustCompile(`{path\.([\w-]*)}`), "{http.request.uri.path.$1}"}, {regexp.MustCompile(`{re\.([\w-]*)\.([\w-]*)}`), "{http.regexp.$1.$2}"}, {regexp.MustCompile(`{vars\.([\w-]*)}`), "{http.vars.$1}"}, + {regexp.MustCompile(`{rp\.([\w-\.]*)}`), "{http.reverse_proxy.$1}"}, } for _, sb := range originalServerBlocks { -- cgit v1.2.3