From 9bdd6caa0bcced5caf30872548700277f2db1877 Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Sat, 8 Feb 2020 22:26:31 +0300 Subject: v2: Implement RegExp Vars Matcher (#2997) * implement regexp var matcher * use subtests pattern for tests * be more consistent with naming: MatchVarRE -> MatchVarsRE, var_regexp -> vars_regexp --- modules/caddyhttp/matchers_test.go | 86 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'modules/caddyhttp/matchers_test.go') diff --git a/modules/caddyhttp/matchers_test.go b/modules/caddyhttp/matchers_test.go index 06f137e..58df171 100644 --- a/modules/caddyhttp/matchers_test.go +++ b/modules/caddyhttp/matchers_test.go @@ -545,6 +545,92 @@ func TestHeaderREMatcher(t *testing.T) { } } +func TestVarREMatcher(t *testing.T) { + for i, tc := range []struct { + desc string + match MatchVarsRE + input VarsMiddleware + expect bool + expectRepl map[string]string + }{ + { + desc: "match static value within var set by the VarsMiddleware succeeds", + match: MatchVarsRE{"Var1": &MatchRegexp{Pattern: "foo"}}, + input: VarsMiddleware{"Var1": "here is foo val"}, + expect: true, + }, + { + desc: "value set by VarsMiddleware not satisfying regexp matcher fails to match", + match: MatchVarsRE{"Var1": &MatchRegexp{Pattern: "$foo^"}}, + input: VarsMiddleware{"Var1": "foobar"}, + expect: false, + }, + { + desc: "successfully matched value is captured and its placeholder is added to replacer", + match: MatchVarsRE{"Var1": &MatchRegexp{Pattern: "^foo(.*)$", Name: "name"}}, + input: VarsMiddleware{"Var1": "foobar"}, + expect: true, + expectRepl: map[string]string{"name.1": "bar"}, + }, + { + desc: "matching against a value of standard variables succeeds", + match: MatchVarsRE{"{http.request.method}": &MatchRegexp{Pattern: "^G.[tT]$"}}, + input: VarsMiddleware{}, + expect: true, + }, + { + desc: "matching agaist value of var set by the VarsMiddleware and referenced by its placeholder succeeds", + match: MatchVarsRE{"{http.vars.Var1}": &MatchRegexp{Pattern: "[vV]ar[0-9]"}}, + input: VarsMiddleware{"Var1": "var1Value"}, + expect: true, + }, + } { + tc := tc // capture range value + t.Run(tc.desc, func(t *testing.T) { + t.Parallel() + // compile the regexp and validate its name + err := tc.match.Provision(caddy.Context{}) + if err != nil { + t.Errorf("Test %d %v: Provisioning: %v", i, tc.match, err) + return + } + err = tc.match.Validate() + if err != nil { + t.Errorf("Test %d %v: Validating: %v", i, tc.match, err) + return + } + + // set up the fake request and its Replacer + req := &http.Request{URL: new(url.URL), Method: http.MethodGet} + repl := caddy.NewReplacer() + ctx := context.WithValue(req.Context(), caddy.ReplacerCtxKey, repl) + ctx = context.WithValue(ctx, VarsCtxKey, make(map[string]interface{})) + req = req.WithContext(ctx) + + addHTTPVarsToReplacer(repl, req, httptest.NewRecorder()) + + tc.input.ServeHTTP(httptest.NewRecorder(), req, emptyHandler) + + actual := tc.match.Match(req) + if actual != tc.expect { + t.Errorf("Test %d [%v]: Expected %t, got %t for input '%s'", + i, tc.match, tc.expect, actual, tc.input) + return + } + + for key, expectVal := range tc.expectRepl { + placeholder := fmt.Sprintf("{http.regexp.%s}", key) + actualVal := repl.ReplaceAll(placeholder, "") + if actualVal != expectVal { + t.Errorf("Test %d [%v]: Expected placeholder {http.regexp.%s} to be '%s' but got '%s'", + i, tc.match, key, expectVal, actualVal) + return + } + } + }) + } +} + func TestResponseMatcher(t *testing.T) { for i, tc := range []struct { require ResponseMatcher -- cgit v1.2.3