1// Copyright 2020 The gRPC Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// Local copy of Envoy xDS proto file, used for testing only. 16 17syntax = "proto3"; 18 19package envoy.config.route.v3; 20 21import "src/proto/grpc/testing/xds/v3/base.proto"; 22import "src/proto/grpc/testing/xds/v3/regex.proto"; 23import "src/proto/grpc/testing/xds/v3/percent.proto"; 24import "src/proto/grpc/testing/xds/v3/range.proto"; 25 26import "google/protobuf/duration.proto"; 27import "google/protobuf/wrappers.proto"; 28 29// [#protodoc-title: HTTP route components] 30// * Routing :ref:`architecture overview <arch_overview_http_routing>` 31// * HTTP :ref:`router filter <config_http_filters_router>` 32 33// The top level element in the routing configuration is a virtual host. Each virtual host has 34// a logical name as well as a set of domains that get routed to it based on the incoming request's 35// host header. This allows a single listener to service multiple top level domain path trees. Once 36// a virtual host is selected based on the domain, the routes are processed in order to see which 37// upstream cluster to route to or whether to perform a redirect. 38// [#next-free-field: 21] 39message VirtualHost { 40 // The logical name of the virtual host. This is used when emitting certain 41 // statistics but is not relevant for routing. 42 string name = 1; 43 44 // A list of domains (host/authority header) that will be matched to this 45 // virtual host. Wildcard hosts are supported in the suffix or prefix form. 46 // 47 // Domain search order: 48 // 1. Exact domain names: ``www.foo.com``. 49 // 2. Suffix domain wildcards: ``*.foo.com`` or ``*-bar.foo.com``. 50 // 3. Prefix domain wildcards: ``foo.*`` or ``foo-*``. 51 // 4. Special wildcard ``*`` matching any domain. 52 // 53 // .. note:: 54 // 55 // The wildcard will not match the empty string. 56 // e.g. ``*-bar.foo.com`` will match ``baz-bar.foo.com`` but not ``-bar.foo.com``. 57 // The longest wildcards match first. 58 // Only a single virtual host in the entire route configuration can match on ``*``. A domain 59 // must be unique across all virtual hosts or the config will fail to load. 60 // 61 // Domains cannot contain control characters. This is validated by the well_known_regex HTTP_HEADER_VALUE. 62 repeated string domains = 2; 63 64 // The list of routes that will be matched, in order, for incoming requests. 65 // The first route that matches will be used. 66 repeated Route routes = 3; 67} 68 69// A route is both a specification of how to match a request as well as an indication of what to do 70// next (e.g., redirect, forward, rewrite, etc.). 71// 72// .. attention:: 73// 74// Envoy supports routing on HTTP method via :ref:`header matching 75// <envoy_api_msg_config.route.v3.HeaderMatcher>`. 76// [#next-free-field: 18] 77message Route { 78 // Name for the route. 79 string name = 14; 80 81 // Route matching parameters. 82 RouteMatch match = 1; 83 84 oneof action { 85 // Route request to some upstream cluster. 86 RouteAction route = 2; 87 88 // Return a redirect. 89 RedirectAction redirect = 3; 90 } 91} 92 93// Compared to the :ref:`cluster <envoy_api_field_config.route.v3.RouteAction.cluster>` field that specifies a 94// single upstream cluster as the target of a request, the :ref:`weighted_clusters 95// <envoy_api_field_config.route.v3.RouteAction.weighted_clusters>` option allows for specification of 96// multiple upstream clusters along with weights that indicate the percentage of 97// traffic to be forwarded to each cluster. The router selects an upstream cluster based on the 98// weights. 99message WeightedCluster { 100 // [#next-free-field: 11] 101 message ClusterWeight { 102 // Name of the upstream cluster. The cluster must exist in the 103 // :ref:`cluster manager configuration <config_cluster_manager>`. 104 string name = 1; 105 106 // An integer between 0 and :ref:`total_weight 107 // <envoy_api_field_config.route.v3.WeightedCluster.total_weight>`. When a request matches the route, 108 // the choice of an upstream cluster is determined by its weight. The sum of weights across all 109 // entries in the clusters array must add up to the total_weight, which defaults to 100. 110 google.protobuf.UInt32Value weight = 2; 111 } 112 113 // Specifies one or more upstream clusters associated with the route. 114 repeated ClusterWeight clusters = 1; 115 116 // Specifies the total weight across all clusters. The sum of all cluster weights must equal this 117 // value, which must be greater than 0. Defaults to 100. 118 google.protobuf.UInt32Value total_weight = 3; 119} 120 121// [#next-free-field: 13] 122message RouteMatch { 123 oneof path_specifier { 124 // If specified, the route is a prefix rule meaning that the prefix must 125 // match the beginning of the *:path* header. 126 string prefix = 1; 127 128 // If specified, the route is an exact path rule meaning that the path must 129 // exactly match the *:path* header once the query string is removed. 130 string path = 2; 131 132 // If specified, the route is a regular expression rule meaning that the 133 // regex must match the *:path* header once the query string is removed. The entire path 134 // (without the query string) must match the regex. The rule will not match if only a 135 // subsequence of the *:path* header matches the regex. 136 // 137 // [#next-major-version: In the v3 API we should redo how path specification works such 138 // that we utilize StringMatcher, and additionally have consistent options around whether we 139 // strip query strings, do a case sensitive match, etc. In the interim it will be too disruptive 140 // to deprecate the existing options. We should even consider whether we want to do away with 141 // path_specifier entirely and just rely on a set of header matchers which can already match 142 // on :path, etc. The issue with that is it is unclear how to generically deal with query string 143 // stripping. This needs more thought.] 144 type.matcher.v3.RegexMatcher safe_regex = 10; 145 } 146 147 // Indicates that prefix/path matching should be case insensitive. The default 148 // is true. 149 google.protobuf.BoolValue case_sensitive = 4; 150 151 // Indicates that the route should additionally match on a runtime key. Every time the route 152 // is considered for a match, it must also fall under the percentage of matches indicated by 153 // this field. For some fraction N/D, a random number in the range [0,D) is selected. If the 154 // number is <= the value of the numerator N, or if the key is not present, the default 155 // value, the router continues to evaluate the remaining match criteria. A runtime_fraction 156 // route configuration can be used to roll out route changes in a gradual manner without full 157 // code/config deploys. Refer to the :ref:`traffic shifting 158 // <config_http_conn_man_route_table_traffic_splitting_shift>` docs for additional documentation. 159 // 160 // .. note:: 161 // 162 // Parsing this field is implemented such that the runtime key's data may be represented 163 // as a FractionalPercent proto represented as JSON/YAML and may also be represented as an 164 // integer with the assumption that the value is an integral percentage out of 100. For 165 // instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent 166 // whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics. 167 core.v3.RuntimeFractionalPercent runtime_fraction = 9; 168 169 // Specifies a set of headers that the route should match on. The router will 170 // check the request’s headers against all the specified headers in the route 171 // config. A match will happen if all the headers in the route are present in 172 // the request with the same values (or based on presence if the value field 173 // is not in the config). 174 repeated HeaderMatcher headers = 6; 175 176 // Specifies a set of URL query parameters on which the route should 177 // match. The router will check the query string from the *path* header 178 // against all the specified query parameters. If the number of specified 179 // query parameters is nonzero, they all must match the *path* header's 180 // query string for a match to occur. 181 repeated QueryParameterMatcher query_parameters = 7; 182} 183 184message MaxStreamDuration { 185 // Specifies the maximum duration allowed for streams on the route. If not specified, the value 186 // from the :ref:`max_stream_duration 187 // <envoy_api_field_config.core.v3.HttpProtocolOptions.max_stream_duration>` field in 188 // :ref:`HttpConnectionManager.common_http_protocol_options 189 // <envoy_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options>` 190 // is used. If this field is set explicitly to zero, any 191 // HttpConnectionManager max_stream_duration timeout will be disabled for 192 // this route. 193 google.protobuf.Duration max_stream_duration = 1; 194 195 // If present, and the request contains a `grpc-timeout header 196 // <https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md>`_, use that value as the 197 // *max_stream_duration*, but limit the applied timeout to the maximum value specified here. 198 // If set to 0, the `grpc-timeout` header is used without modification. 199 google.protobuf.Duration grpc_timeout_header_max = 2; 200} 201 202// [#next-free-field: 37] 203message RouteAction { 204 oneof cluster_specifier { 205 // Indicates the upstream cluster to which the request should be routed 206 // to. 207 string cluster = 1; 208 209 // Envoy will determine the cluster to route to by reading the value of the 210 // HTTP header named by cluster_header from the request headers. If the 211 // header is not found or the referenced cluster does not exist, Envoy will 212 // return a 404 response. 213 // 214 // .. attention:: 215 // 216 // Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 217 // *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. 218 string cluster_header = 2; 219 220 // Multiple upstream clusters can be specified for a given route. The 221 // request is routed to one of the upstream clusters based on weights 222 // assigned to each cluster. See 223 // :ref:`traffic splitting <config_http_conn_man_route_table_traffic_splitting_split>` 224 // for additional documentation. 225 WeightedCluster weighted_clusters = 3; 226 } 227 // Specifies the maximum stream duration for this route. 228 MaxStreamDuration max_stream_duration = 36; 229} 230 231// .. attention:: 232// 233// Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 *Host* 234// header. Thus, if attempting to match on *Host*, match on *:authority* instead. 235// 236// .. attention:: 237// 238// To route on HTTP method, use the special HTTP/2 *:method* header. This works for both 239// HTTP/1 and HTTP/2 as Envoy normalizes headers. E.g., 240// 241// .. code-block:: json 242// 243// { 244// "name": ":method", 245// "exact_match": "POST" 246// } 247// 248// .. attention:: 249// In the absence of any header match specifier, match will default to :ref:`present_match 250// <envoy_api_field_config.route.v3.HeaderMatcher.present_match>`. i.e, a request that has the :ref:`name 251// <envoy_api_field_config.route.v3.HeaderMatcher.name>` header will match, regardless of the header's 252// value. 253// 254// [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] 255// [#next-free-field: 12] 256message HeaderMatcher { 257 // Specifies the name of the header in the request. 258 string name = 1; 259 260 // Specifies how the header match will be performed to route the request. 261 oneof header_match_specifier { 262 // If specified, header match will be performed based on the value of the header. 263 string exact_match = 4; 264 265 // If specified, this regex string is a regular expression rule which implies the entire request 266 // header value must match the regex. The rule will not match if only a subsequence of the 267 // request header value matches the regex. 268 type.matcher.v3.RegexMatcher safe_regex_match = 11; 269 270 // If specified, header match will be performed based on range. 271 // The rule will match if the request header value is within this range. 272 // The entire request header value must represent an integer in base 10 notation: consisting of 273 // an optional plus or minus sign followed by a sequence of digits. The rule will not match if 274 // the header value does not represent an integer. Match will fail for empty values, floating 275 // point numbers or if only a subsequence of the header value is an integer. 276 // 277 // Examples: 278 // 279 // * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9, 280 // "-1somestring" 281 type.v3.Int64Range range_match = 6; 282 283 // If specified, header match will be performed based on whether the header is in the 284 // request. 285 bool present_match = 7; 286 287 // If specified, header match will be performed based on the prefix of the header value. 288 // Note: empty prefix is not allowed, please use present_match instead. 289 // 290 // Examples: 291 // 292 // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*. 293 string prefix_match = 9; 294 295 // If specified, header match will be performed based on the suffix of the header value. 296 // Note: empty suffix is not allowed, please use present_match instead. 297 // 298 // Examples: 299 // 300 // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. 301 string suffix_match = 10; 302 } 303 304 // If specified, the match result will be inverted before checking. Defaults to false. 305 // 306 // Examples: 307 // 308 // * The regex ``\d{3}`` does not match the value *1234*, so it will match when inverted. 309 // * The range [-10,0) will match the value -1, so it will not match when inverted. 310 bool invert_match = 8; 311} 312 313// Query parameter matching treats the query string of a request's :path header 314// as an ampersand-separated list of keys and/or key=value elements. 315// [#next-free-field: 7] 316message QueryParameterMatcher { 317} 318 319// [#protodoc-title: HTTP route configuration] 320// * Routing :ref:`architecture overview <arch_overview_http_routing>` 321// * HTTP :ref:`router filter <config_http_filters_router>` 322 323// [#next-free-field: 11] 324message RouteConfiguration { 325 // The name of the route configuration. For example, it might match 326 // :ref:`route_config_name 327 // <envoy_api_field_extensions.filters.network.http_connection_manager.v3.Rds.route_config_name>` in 328 // :ref:`envoy_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. 329 string name = 1; 330 331 // An array of virtual hosts that make up the route table. 332 repeated VirtualHost virtual_hosts = 2; 333} 334 335message RedirectAction { 336} 337