From 2883b6340f5083883566caad8cca1863e5cca7a2 Mon Sep 17 00:00:00 2001 From: Charlie Vieth Date: Wed, 19 Nov 2025 22:27:29 -0500 Subject: [PATCH] plugin/rewrite: pre-compile CNMAE rewrite regexp (#7697) This commit changes the CNAME rewrite rule to use a pre-compiled regexp when the match type is RegexMatch instead of compiling it on-the-fly for each request. This will also allow for invalid regexp patterns to be identified during setup instead of causing a panic when the rule is first invoked. Signed-off-by: Charlie Vieth --- plugin/rewrite/cname_target.go | 13 ++++++++++--- plugin/rewrite/setup_test.go | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/plugin/rewrite/cname_target.go b/plugin/rewrite/cname_target.go index e87db72cc..46d501801 100644 --- a/plugin/rewrite/cname_target.go +++ b/plugin/rewrite/cname_target.go @@ -25,7 +25,8 @@ type cnameTargetRule struct { paramFromTarget string paramToTarget string nextAction string - Upstream UpstreamInt // Upstream for looking up external names during the resolution process. + pattern *regexp.Regexp // Compiled paramFromTarget regex for RegexMatch + Upstream UpstreamInt // Upstream for looking up external names during the resolution process. } // cnameTargetRuleWithReqState is cname target rewrite rule state @@ -52,8 +53,7 @@ func (r *cnameTargetRule) getFromAndToTarget(inputCName string) (from string, to return inputCName, strings.ReplaceAll(inputCName, r.paramFromTarget, r.paramToTarget) } case RegexMatch: - pattern := regexp.MustCompile(r.paramFromTarget) - regexGroups := pattern.FindStringSubmatch(inputCName) + regexGroups := r.pattern.FindStringSubmatch(inputCName) if len(regexGroups) == 0 { return "", "" } @@ -143,6 +143,13 @@ func newCNAMERule(nextAction string, args ...string) (Rule, error) { nextAction: nextAction, Upstream: upstream.New(), } + if rewriteType == RegexMatch { + re, err := regexp.Compile(paramFromTarget) + if err != nil { + return nil, fmt.Errorf("invalid cname rewrite regex pattern: %w", err) + } + rule.pattern = re + } return &rule, nil } diff --git a/plugin/rewrite/setup_test.go b/plugin/rewrite/setup_test.go index 88d332fb4..76bbe0c6a 100644 --- a/plugin/rewrite/setup_test.go +++ b/plugin/rewrite/setup_test.go @@ -33,6 +33,7 @@ func TestParse(t *testing.T) { }`, true, "must begin with a name rule"}, {`rewrite stop`, true, ""}, {`rewrite continue`, true, ""}, + {`rewrite stop name regex [bad[ bar answer name bar foo`, true, ""}, } for i, test := range tests {