diff --git a/xds/internal/client/client.go b/xds/internal/client/client.go index 2daceede5398..7e86f396a3a4 100644 --- a/xds/internal/client/client.go +++ b/xds/internal/client/client.go @@ -24,6 +24,7 @@ import ( "context" "errors" "fmt" + "regexp" "sync" "time" @@ -271,7 +272,9 @@ type VirtualHost struct { // Route is both a specification of how to match a request as well as an // indication of the action to take upon match. type Route struct { - Path, Prefix, Regex *string + Path *string + Prefix *string + Regex *regexp.Regexp // Indicates if prefix/path matching should be case insensitive. The default // is false (case sensitive). CaseInsensitive bool @@ -304,14 +307,14 @@ type WeightedCluster struct { // HeaderMatcher represents header matchers. type HeaderMatcher struct { - Name string `json:"name"` - InvertMatch *bool `json:"invertMatch,omitempty"` - ExactMatch *string `json:"exactMatch,omitempty"` - RegexMatch *string `json:"regexMatch,omitempty"` - PrefixMatch *string `json:"prefixMatch,omitempty"` - SuffixMatch *string `json:"suffixMatch,omitempty"` - RangeMatch *Int64Range `json:"rangeMatch,omitempty"` - PresentMatch *bool `json:"presentMatch,omitempty"` + Name string `json:"name"` + InvertMatch *bool `json:"invertMatch,omitempty"` + ExactMatch *string `json:"exactMatch,omitempty"` + RegexMatch *regexp.Regexp `json:"regexMatch,omitempty"` + PrefixMatch *string `json:"prefixMatch,omitempty"` + SuffixMatch *string `json:"suffixMatch,omitempty"` + RangeMatch *Int64Range `json:"rangeMatch,omitempty"` + PresentMatch *bool `json:"presentMatch,omitempty"` } // Int64Range is a range for header range match. diff --git a/xds/internal/client/xds.go b/xds/internal/client/xds.go index 43e1908cd958..55bcc2e936ca 100644 --- a/xds/internal/client/xds.go +++ b/xds/internal/client/xds.go @@ -439,11 +439,11 @@ func routesProtoToSlice(routes []*v3routepb.Route, logger *grpclog.PrefixLogger, route.Path = &pt.Path case *v3routepb.RouteMatch_SafeRegex: regex := pt.SafeRegex.GetRegex() - _, err := regexp.Compile(regex) + re, err := regexp.Compile(regex) if err != nil { return nil, fmt.Errorf("route %+v contains an invalid regex %q", r, regex) } - route.Regex = ®ex + route.Regex = re default: return nil, fmt.Errorf("route %+v has an unrecognized path specifier: %+v", r, pt) } @@ -459,11 +459,11 @@ func routesProtoToSlice(routes []*v3routepb.Route, logger *grpclog.PrefixLogger, header.ExactMatch = &ht.ExactMatch case *v3routepb.HeaderMatcher_SafeRegexMatch: regex := ht.SafeRegexMatch.GetRegex() - _, err := regexp.Compile(regex) + re, err := regexp.Compile(regex) if err != nil { return nil, fmt.Errorf("route %+v contains an invalid regex %q", r, regex) } - header.RegexMatch = ®ex + header.RegexMatch = re case *v3routepb.HeaderMatcher_RangeMatch: header.RangeMatch = &Int64Range{ Start: ht.RangeMatch.Start, diff --git a/xds/internal/resolver/matcher.go b/xds/internal/resolver/matcher.go index b7b5f3db0e3e..06456a585573 100644 --- a/xds/internal/resolver/matcher.go +++ b/xds/internal/resolver/matcher.go @@ -20,7 +20,6 @@ package resolver import ( "fmt" - "regexp" "strings" "google.golang.org/grpc/internal/grpcrand" @@ -34,11 +33,7 @@ func routeToMatcher(r *xdsclient.Route) (*compositeMatcher, error) { var pathMatcher pathMatcherInterface switch { case r.Regex != nil: - re, err := regexp.Compile(*r.Regex) - if err != nil { - return nil, fmt.Errorf("failed to compile regex %q", *r.Regex) - } - pathMatcher = newPathRegexMatcher(re) + pathMatcher = newPathRegexMatcher(r.Regex) case r.Path != nil: pathMatcher = newPathExactMatcher(*r.Path, r.CaseInsensitive) case r.Prefix != nil: @@ -53,12 +48,8 @@ func routeToMatcher(r *xdsclient.Route) (*compositeMatcher, error) { switch { case h.ExactMatch != nil && *h.ExactMatch != "": matcherT = newHeaderExactMatcher(h.Name, *h.ExactMatch) - case h.RegexMatch != nil && *h.RegexMatch != "": - re, err := regexp.Compile(*h.RegexMatch) - if err != nil { - return nil, fmt.Errorf("failed to compile regex %q, skipping this matcher", *h.RegexMatch) - } - matcherT = newHeaderRegexMatcher(h.Name, re) + case h.RegexMatch != nil: + matcherT = newHeaderRegexMatcher(h.Name, h.RegexMatch) case h.PrefixMatch != nil && *h.PrefixMatch != "": matcherT = newHeaderPrefixMatcher(h.Name, *h.PrefixMatch) case h.SuffixMatch != nil && *h.SuffixMatch != "":