xref: /aosp_15_r20/external/grpc-grpc-java/xds/src/main/java/io/grpc/xds/internal/MatcherParser.java (revision e07d83d3ffcef9ecfc9f7f475418ec639ff0e5fe)
1 /*
2  * Copyright 2021 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.xds.internal;
18 
19 import com.google.re2j.Pattern;
20 import com.google.re2j.PatternSyntaxException;
21 
22 // TODO(zivy@): may reuse common matchers parsers.
23 public final class MatcherParser {
24   /** Translates envoy proto HeaderMatcher to internal HeaderMatcher.*/
parseHeaderMatcher( io.envoyproxy.envoy.config.route.v3.HeaderMatcher proto)25   public static Matchers.HeaderMatcher parseHeaderMatcher(
26           io.envoyproxy.envoy.config.route.v3.HeaderMatcher proto) {
27     switch (proto.getHeaderMatchSpecifierCase()) {
28       case EXACT_MATCH:
29         return Matchers.HeaderMatcher.forExactValue(
30                         proto.getName(), proto.getExactMatch(), proto.getInvertMatch());
31       case SAFE_REGEX_MATCH:
32         String rawPattern = proto.getSafeRegexMatch().getRegex();
33         Pattern safeRegExMatch;
34         try {
35           safeRegExMatch = Pattern.compile(rawPattern);
36         } catch (PatternSyntaxException e) {
37           throw new IllegalArgumentException(
38                 "HeaderMatcher [" + proto.getName() + "] contains malformed safe regex pattern: "
39                         + e.getMessage());
40         }
41         return Matchers.HeaderMatcher.forSafeRegEx(
42               proto.getName(), safeRegExMatch, proto.getInvertMatch());
43       case RANGE_MATCH:
44         Matchers.HeaderMatcher.Range rangeMatch = Matchers.HeaderMatcher.Range.create(
45               proto.getRangeMatch().getStart(), proto.getRangeMatch().getEnd());
46         return Matchers.HeaderMatcher.forRange(
47               proto.getName(), rangeMatch, proto.getInvertMatch());
48       case PRESENT_MATCH:
49         return Matchers.HeaderMatcher.forPresent(
50               proto.getName(), proto.getPresentMatch(), proto.getInvertMatch());
51       case PREFIX_MATCH:
52         return Matchers.HeaderMatcher.forPrefix(
53               proto.getName(), proto.getPrefixMatch(), proto.getInvertMatch());
54       case SUFFIX_MATCH:
55         return Matchers.HeaderMatcher.forSuffix(
56               proto.getName(), proto.getSuffixMatch(), proto.getInvertMatch());
57       case CONTAINS_MATCH:
58         return Matchers.HeaderMatcher.forContains(
59               proto.getName(), proto.getContainsMatch(), proto.getInvertMatch());
60       case STRING_MATCH:
61         return Matchers.HeaderMatcher.forString(
62           proto.getName(), parseStringMatcher(proto.getStringMatch()), proto.getInvertMatch());
63       case HEADERMATCHSPECIFIER_NOT_SET:
64       default:
65         throw new IllegalArgumentException(
66                 "Unknown header matcher type: " + proto.getHeaderMatchSpecifierCase());
67     }
68   }
69 
70   /** Translate StringMatcher envoy proto to internal StringMatcher. */
parseStringMatcher( io.envoyproxy.envoy.type.matcher.v3.StringMatcher proto)71   public static Matchers.StringMatcher parseStringMatcher(
72             io.envoyproxy.envoy.type.matcher.v3.StringMatcher proto) {
73     switch (proto.getMatchPatternCase()) {
74       case EXACT:
75         return Matchers.StringMatcher.forExact(proto.getExact(), proto.getIgnoreCase());
76       case PREFIX:
77         return Matchers.StringMatcher.forPrefix(proto.getPrefix(), proto.getIgnoreCase());
78       case SUFFIX:
79         return Matchers.StringMatcher.forSuffix(proto.getSuffix(), proto.getIgnoreCase());
80       case SAFE_REGEX:
81         return Matchers.StringMatcher.forSafeRegEx(
82                 Pattern.compile(proto.getSafeRegex().getRegex()));
83       case CONTAINS:
84         return Matchers.StringMatcher.forContains(proto.getContains());
85       case MATCHPATTERN_NOT_SET:
86       default:
87         throw new IllegalArgumentException(
88                 "Unknown StringMatcher match pattern: " + proto.getMatchPatternCase());
89     }
90   }
91 }
92