|  |  | @ -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, "<empty>") | 
			
		
	
		
			
				
					|  |  |  | 				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 | 
			
		
	
	
		
			
				
					|  |  | 
 |