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