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 <charlie.vieth@gmail.com>
This commit is contained in:
Charlie Vieth
2025-11-19 22:27:29 -05:00
committed by GitHub
parent e56971b253
commit 2883b6340f
2 changed files with 11 additions and 3 deletions

View File

@@ -25,7 +25,8 @@ type cnameTargetRule struct {
paramFromTarget string paramFromTarget string
paramToTarget string paramToTarget string
nextAction 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 // 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) return inputCName, strings.ReplaceAll(inputCName, r.paramFromTarget, r.paramToTarget)
} }
case RegexMatch: case RegexMatch:
pattern := regexp.MustCompile(r.paramFromTarget) regexGroups := r.pattern.FindStringSubmatch(inputCName)
regexGroups := pattern.FindStringSubmatch(inputCName)
if len(regexGroups) == 0 { if len(regexGroups) == 0 {
return "", "" return "", ""
} }
@@ -143,6 +143,13 @@ func newCNAMERule(nextAction string, args ...string) (Rule, error) {
nextAction: nextAction, nextAction: nextAction,
Upstream: upstream.New(), 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 return &rule, nil
} }

View File

@@ -33,6 +33,7 @@ func TestParse(t *testing.T) {
}`, true, "must begin with a name rule"}, }`, true, "must begin with a name rule"},
{`rewrite stop`, true, ""}, {`rewrite stop`, true, ""},
{`rewrite continue`, true, ""}, {`rewrite continue`, true, ""},
{`rewrite stop name regex [bad[ bar answer name bar foo`, true, ""},
} }
for i, test := range tests { for i, test := range tests {