Line data Source code
1 : #pragma once 2 : 3 : #include <optional> 4 : #include <string> 5 : #include <variant> 6 : #include <vector> 7 : 8 : #include "absl/container/flat_hash_set.h" 9 : #include "absl/status/status.h" 10 : #include "absl/status/statusor.h" 11 : #include "absl/strings/string_view.h" 12 : #include "absl/types/optional.h" 13 : #include "absl/types/variant.h" 14 : #include "re2/re2.h" 15 : 16 : namespace Envoy { 17 : namespace Extensions { 18 : namespace UriTemplate { 19 : 20 : namespace Internal { 21 : 22 : /** 23 : * String to be concatenated in rewritten path. 24 : */ 25 : using Literal = absl::string_view; 26 : 27 : /** 28 : * Determines what operations to use on the input pattern segment. 29 : */ 30 : enum class Operator { PathGlob, TextGlob }; 31 : 32 : /** 33 : * Represents a pattern variable. Variables are included in both path match and rewrite paths. 34 : */ 35 : struct Variable { 36 : Variable(absl::string_view name, std::vector<absl::variant<Operator, Literal>> match) 37 546 : : name_(name), match_(match) {} 38 : 39 : std::string debugString() const; 40 : 41 : absl::string_view name_; 42 : 43 : // The pattern which this variable matches. 44 : std::vector<absl::variant<Operator, Literal>> match_; 45 : }; 46 : 47 : using ParsedSegment = absl::variant<Operator, Variable, Literal>; 48 : 49 : /** 50 : * Represents the parsed path including literals and variables. 51 : */ 52 : struct ParsedPathPattern { 53 : std::vector<ParsedSegment> parsed_segments_; 54 : 55 : // Suffix holds end of path that matched a wildcard. 56 : // For example: 57 : // Pattern: /foo/bar/** 58 : // Path: /foo/bar/some/more/stuff 59 : // Suffix: some/more/stuff 60 : absl::string_view suffix_; 61 : absl::flat_hash_set<absl::string_view> captured_variables_; 62 : 63 : std::string debugString() const; 64 : }; 65 : 66 : /** 67 : * Returns true if `literal` is valid for pattern match. 68 : * (does not contain wildcards, forwards slashes, or curly brackets). 69 : */ 70 : bool isValidLiteral(absl::string_view literal); 71 : 72 : /** 73 : * Returns true if `literal` is valid for pattern rewrite. 74 : * (does not contain wildcards or curly brackets). 75 : */ 76 : bool isValidRewriteLiteral(absl::string_view literal); 77 : 78 : /** 79 : * Return true if variable name is valid. 80 : */ 81 : bool isValidVariableName(absl::string_view variable); 82 : 83 : /** 84 : * Used by the following Parse{Literal,Operator,Variable} functions 85 : * in the return value. The functions would take the given pattern, 86 : * parse what it can into |parsed_value| and return the unparsed 87 : * portion of the pattern in |unparsed_pattern|. 88 : */ 89 : template <typename T> struct ParsedResult { 90 1281 : ParsedResult(T val, absl::string_view pattern) : parsed_value_(val), unparsed_pattern_(pattern) {} 91 : 92 : T parsed_value_; 93 : absl::string_view unparsed_pattern_; 94 : }; 95 : 96 : /** 97 : * Parses a literal in the front of `pattern` and returns the literal and remaining pattern. 98 : */ 99 : absl::StatusOr<ParsedResult<Literal>> parseLiteral(absl::string_view pattern); 100 : 101 : /** 102 : * Parses a operator in the front of `pattern` and returns the operator and remaining pattern. 103 : */ 104 : absl::StatusOr<ParsedResult<Operator>> parseOperator(absl::string_view pattern); 105 : 106 : /** 107 : * Parses a variable in the front of `pattern`. 108 : */ 109 : absl::StatusOr<ParsedResult<Variable>> parseVariable(absl::string_view pattern); 110 : 111 : /** 112 : * Converts input path to ParsedPathPattern. 113 : * ParsedPathPattern hold prefix, string literals, and variables for rewrite. 114 : */ 115 : absl::StatusOr<ParsedPathPattern> parsePathPatternSyntax(absl::string_view path); 116 : 117 : /** 118 : * Convert Literal to a re2-compatible regular expression. 119 : */ 120 : std::string toRegexPattern(Literal pattern); 121 : 122 : /** 123 : * Converts Operator to a regex string representation. 124 : */ 125 : std::string toRegexPattern(Operator pattern); 126 : 127 : /** 128 : * Converts Variable to a regex string representation. 129 : */ 130 : std::string toRegexPattern(const Variable& pattern); 131 : 132 : /** 133 : * Converts ParsedPathPattern to a regex string representation. 134 : */ 135 : std::string toRegexPattern(const struct ParsedPathPattern& pattern); 136 : 137 : /** 138 : * Checks end of pattern to ensure glob operator is last. 139 : */ 140 : absl::Status validateNoOperatorAfterTextGlob(const struct ParsedPathPattern& pattern); 141 : 142 : } // namespace Internal 143 : } // namespace UriTemplate 144 : } // namespace Extensions 145 : } // namespace Envoy