| // Copyright 2020 The gRPC Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // Local copy of Envoy xDS proto file, used for testing only. |
| |
| syntax = "proto3"; |
| |
| package envoy.config.route.v3; |
| |
| import "src/proto/grpc/testing/xds/v3/base.proto"; |
| import "src/proto/grpc/testing/xds/v3/regex.proto"; |
| import "src/proto/grpc/testing/xds/v3/percent.proto"; |
| import "src/proto/grpc/testing/xds/v3/range.proto"; |
| |
| import "google/protobuf/any.proto"; |
| import "google/protobuf/duration.proto"; |
| import "google/protobuf/wrappers.proto"; |
| |
| // [#protodoc-title: HTTP route components] |
| // * Routing :ref:`architecture overview <arch_overview_http_routing>` |
| // * HTTP :ref:`router filter <config_http_filters_router>` |
| |
| // The top level element in the routing configuration is a virtual host. Each virtual host has |
| // a logical name as well as a set of domains that get routed to it based on the incoming request's |
| // host header. This allows a single listener to service multiple top level domain path trees. Once |
| // a virtual host is selected based on the domain, the routes are processed in order to see which |
| // upstream cluster to route to or whether to perform a redirect. |
| // [#next-free-field: 21] |
| message VirtualHost { |
| // The logical name of the virtual host. This is used when emitting certain |
| // statistics but is not relevant for routing. |
| string name = 1; |
| |
| // A list of domains (host/authority header) that will be matched to this |
| // virtual host. Wildcard hosts are supported in the suffix or prefix form. |
| // |
| // Domain search order: |
| // 1. Exact domain names: ``www.foo.com``. |
| // 2. Suffix domain wildcards: ``*.foo.com`` or ``*-bar.foo.com``. |
| // 3. Prefix domain wildcards: ``foo.*`` or ``foo-*``. |
| // 4. Special wildcard ``*`` matching any domain. |
| // |
| // .. note:: |
| // |
| // The wildcard will not match the empty string. |
| // e.g. ``*-bar.foo.com`` will match ``baz-bar.foo.com`` but not ``-bar.foo.com``. |
| // The longest wildcards match first. |
| // Only a single virtual host in the entire route configuration can match on ``*``. A domain |
| // must be unique across all virtual hosts or the config will fail to load. |
| // |
| // Domains cannot contain control characters. This is validated by the well_known_regex HTTP_HEADER_VALUE. |
| repeated string domains = 2; |
| |
| // The list of routes that will be matched, in order, for incoming requests. |
| // The first route that matches will be used. |
| repeated Route routes = 3; |
| |
| // The per_filter_config field can be used to provide virtual host-specific |
| // configurations for filters. The key should match the filter name, such as |
| // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter |
| // specific; see the :ref:`HTTP filter documentation <config_http_filters>` |
| // for if and how it is utilized. |
| map<string, google.protobuf.Any> typed_per_filter_config = 15; |
| } |
| |
| // A route is both a specification of how to match a request as well as an indication of what to do |
| // next (e.g., redirect, forward, rewrite, etc.). |
| // |
| // .. attention:: |
| // |
| // Envoy supports routing on HTTP method via :ref:`header matching |
| // <envoy_api_msg_config.route.v3.HeaderMatcher>`. |
| // [#next-free-field: 18] |
| message Route { |
| // Name for the route. |
| string name = 14; |
| |
| // Route matching parameters. |
| RouteMatch match = 1; |
| |
| oneof action { |
| // Route request to some upstream cluster. |
| RouteAction route = 2; |
| |
| // Return a redirect. |
| RedirectAction redirect = 3; |
| } |
| |
| // The typed_per_filter_config field can be used to provide route-specific |
| // configurations for filters. The key should match the filter name, such as |
| // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter |
| // specific; see the :ref:`HTTP filter documentation <config_http_filters>` for |
| // if and how it is utilized. |
| map<string, google.protobuf.Any> typed_per_filter_config = 13; |
| } |
| |
| // Compared to the :ref:`cluster <envoy_api_field_config.route.v3.RouteAction.cluster>` field that specifies a |
| // single upstream cluster as the target of a request, the :ref:`weighted_clusters |
| // <envoy_api_field_config.route.v3.RouteAction.weighted_clusters>` option allows for specification of |
| // multiple upstream clusters along with weights that indicate the percentage of |
| // traffic to be forwarded to each cluster. The router selects an upstream cluster based on the |
| // weights. |
| message WeightedCluster { |
| // [#next-free-field: 11] |
| message ClusterWeight { |
| // Name of the upstream cluster. The cluster must exist in the |
| // :ref:`cluster manager configuration <config_cluster_manager>`. |
| string name = 1; |
| |
| // An integer between 0 and :ref:`total_weight |
| // <envoy_api_field_config.route.v3.WeightedCluster.total_weight>`. When a request matches the route, |
| // the choice of an upstream cluster is determined by its weight. The sum of weights across all |
| // entries in the clusters array must add up to the total_weight, which defaults to 100. |
| google.protobuf.UInt32Value weight = 2; |
| |
| // The per_filter_config field can be used to provide weighted cluster-specific |
| // configurations for filters. The key should match the filter name, such as |
| // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter |
| // specific; see the :ref:`HTTP filter documentation <config_http_filters>` |
| // for if and how it is utilized. |
| map<string, google.protobuf.Any> typed_per_filter_config = 10; |
| } |
| |
| // Specifies one or more upstream clusters associated with the route. |
| repeated ClusterWeight clusters = 1; |
| |
| // Specifies the total weight across all clusters. The sum of all cluster weights must equal this |
| // value, which must be greater than 0. Defaults to 100. |
| google.protobuf.UInt32Value total_weight = 3; |
| } |
| |
| // [#next-free-field: 13] |
| message RouteMatch { |
| oneof path_specifier { |
| // If specified, the route is a prefix rule meaning that the prefix must |
| // match the beginning of the *:path* header. |
| string prefix = 1; |
| |
| // If specified, the route is an exact path rule meaning that the path must |
| // exactly match the *:path* header once the query string is removed. |
| string path = 2; |
| |
| // If specified, the route is a regular expression rule meaning that the |
| // regex must match the *:path* header once the query string is removed. The entire path |
| // (without the query string) must match the regex. The rule will not match if only a |
| // subsequence of the *:path* header matches the regex. |
| // |
| // [#next-major-version: In the v3 API we should redo how path specification works such |
| // that we utilize StringMatcher, and additionally have consistent options around whether we |
| // strip query strings, do a case sensitive match, etc. In the interim it will be too disruptive |
| // to deprecate the existing options. We should even consider whether we want to do away with |
| // path_specifier entirely and just rely on a set of header matchers which can already match |
| // on :path, etc. The issue with that is it is unclear how to generically deal with query string |
| // stripping. This needs more thought.] |
| type.matcher.v3.RegexMatcher safe_regex = 10; |
| } |
| |
| // Indicates that prefix/path matching should be case insensitive. The default |
| // is true. |
| google.protobuf.BoolValue case_sensitive = 4; |
| |
| // Indicates that the route should additionally match on a runtime key. Every time the route |
| // is considered for a match, it must also fall under the percentage of matches indicated by |
| // this field. For some fraction N/D, a random number in the range [0,D) is selected. If the |
| // number is <= the value of the numerator N, or if the key is not present, the default |
| // value, the router continues to evaluate the remaining match criteria. A runtime_fraction |
| // route configuration can be used to roll out route changes in a gradual manner without full |
| // code/config deploys. Refer to the :ref:`traffic shifting |
| // <config_http_conn_man_route_table_traffic_splitting_shift>` docs for additional documentation. |
| // |
| // .. note:: |
| // |
| // Parsing this field is implemented such that the runtime key's data may be represented |
| // as a FractionalPercent proto represented as JSON/YAML and may also be represented as an |
| // integer with the assumption that the value is an integral percentage out of 100. For |
| // instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent |
| // whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics. |
| core.v3.RuntimeFractionalPercent runtime_fraction = 9; |
| |
| // Specifies a set of headers that the route should match on. The router will |
| // check the request’s headers against all the specified headers in the route |
| // config. A match will happen if all the headers in the route are present in |
| // the request with the same values (or based on presence if the value field |
| // is not in the config). |
| repeated HeaderMatcher headers = 6; |
| |
| // Specifies a set of URL query parameters on which the route should |
| // match. The router will check the query string from the *path* header |
| // against all the specified query parameters. If the number of specified |
| // query parameters is nonzero, they all must match the *path* header's |
| // query string for a match to occur. |
| repeated QueryParameterMatcher query_parameters = 7; |
| } |
| |
| message MaxStreamDuration { |
| // Specifies the maximum duration allowed for streams on the route. If not specified, the value |
| // from the :ref:`max_stream_duration |
| // <envoy_api_field_config.core.v3.HttpProtocolOptions.max_stream_duration>` field in |
| // :ref:`HttpConnectionManager.common_http_protocol_options |
| // <envoy_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options>` |
| // is used. If this field is set explicitly to zero, any |
| // HttpConnectionManager max_stream_duration timeout will be disabled for |
| // this route. |
| google.protobuf.Duration max_stream_duration = 1; |
| |
| // If present, and the request contains a `grpc-timeout header |
| // <https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md>`_, use that value as the |
| // *max_stream_duration*, but limit the applied timeout to the maximum value specified here. |
| // If set to 0, the `grpc-timeout` header is used without modification. |
| google.protobuf.Duration grpc_timeout_header_max = 2; |
| } |
| |
| // [#next-free-field: 37] |
| message RouteAction { |
| oneof cluster_specifier { |
| // Indicates the upstream cluster to which the request should be routed |
| // to. |
| string cluster = 1; |
| |
| // Envoy will determine the cluster to route to by reading the value of the |
| // HTTP header named by cluster_header from the request headers. If the |
| // header is not found or the referenced cluster does not exist, Envoy will |
| // return a 404 response. |
| // |
| // .. attention:: |
| // |
| // Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 |
| // *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. |
| string cluster_header = 2; |
| |
| // Multiple upstream clusters can be specified for a given route. The |
| // request is routed to one of the upstream clusters based on weights |
| // assigned to each cluster. See |
| // :ref:`traffic splitting <config_http_conn_man_route_table_traffic_splitting_split>` |
| // for additional documentation. |
| WeightedCluster weighted_clusters = 3; |
| } |
| // Specifies the maximum stream duration for this route. |
| MaxStreamDuration max_stream_duration = 36; |
| } |
| |
| // .. attention:: |
| // |
| // Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 *Host* |
| // header. Thus, if attempting to match on *Host*, match on *:authority* instead. |
| // |
| // .. attention:: |
| // |
| // To route on HTTP method, use the special HTTP/2 *:method* header. This works for both |
| // HTTP/1 and HTTP/2 as Envoy normalizes headers. E.g., |
| // |
| // .. code-block:: json |
| // |
| // { |
| // "name": ":method", |
| // "exact_match": "POST" |
| // } |
| // |
| // .. attention:: |
| // In the absence of any header match specifier, match will default to :ref:`present_match |
| // <envoy_api_field_config.route.v3.HeaderMatcher.present_match>`. i.e, a request that has the :ref:`name |
| // <envoy_api_field_config.route.v3.HeaderMatcher.name>` header will match, regardless of the header's |
| // value. |
| // |
| // [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] |
| // [#next-free-field: 12] |
| message HeaderMatcher { |
| // Specifies the name of the header in the request. |
| string name = 1; |
| |
| // Specifies how the header match will be performed to route the request. |
| oneof header_match_specifier { |
| // If specified, header match will be performed based on the value of the header. |
| string exact_match = 4; |
| |
| // If specified, this regex string is a regular expression rule which implies the entire request |
| // header value must match the regex. The rule will not match if only a subsequence of the |
| // request header value matches the regex. |
| type.matcher.v3.RegexMatcher safe_regex_match = 11; |
| |
| // If specified, header match will be performed based on range. |
| // The rule will match if the request header value is within this range. |
| // The entire request header value must represent an integer in base 10 notation: consisting of |
| // an optional plus or minus sign followed by a sequence of digits. The rule will not match if |
| // the header value does not represent an integer. Match will fail for empty values, floating |
| // point numbers or if only a subsequence of the header value is an integer. |
| // |
| // Examples: |
| // |
| // * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9, |
| // "-1somestring" |
| type.v3.Int64Range range_match = 6; |
| |
| // If specified, header match will be performed based on whether the header is in the |
| // request. |
| bool present_match = 7; |
| |
| // If specified, header match will be performed based on the prefix of the header value. |
| // Note: empty prefix is not allowed, please use present_match instead. |
| // |
| // Examples: |
| // |
| // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*. |
| string prefix_match = 9; |
| |
| // If specified, header match will be performed based on the suffix of the header value. |
| // Note: empty suffix is not allowed, please use present_match instead. |
| // |
| // Examples: |
| // |
| // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*. |
| string suffix_match = 10; |
| } |
| |
| // If specified, the match result will be inverted before checking. Defaults to false. |
| // |
| // Examples: |
| // |
| // * The regex ``\d{3}`` does not match the value *1234*, so it will match when inverted. |
| // * The range [-10,0) will match the value -1, so it will not match when inverted. |
| bool invert_match = 8; |
| } |
| |
| // Query parameter matching treats the query string of a request's :path header |
| // as an ampersand-separated list of keys and/or key=value elements. |
| // [#next-free-field: 7] |
| message QueryParameterMatcher { |
| } |
| |
| // [#protodoc-title: HTTP route configuration] |
| // * Routing :ref:`architecture overview <arch_overview_http_routing>` |
| // * HTTP :ref:`router filter <config_http_filters_router>` |
| |
| // [#next-free-field: 11] |
| message RouteConfiguration { |
| // The name of the route configuration. For example, it might match |
| // :ref:`route_config_name |
| // <envoy_api_field_extensions.filters.network.http_connection_manager.v3.Rds.route_config_name>` in |
| // :ref:`envoy_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. |
| string name = 1; |
| |
| // An array of virtual hosts that make up the route table. |
| repeated VirtualHost virtual_hosts = 2; |
| } |
| |
| message RedirectAction { |
| } |
| |
| message FilterConfig { |
| // The filter config. |
| google.protobuf.Any config = 1; |
| |
| // If true, the filter is optional, meaning that if the client does |
| // not support the specified filter, it may ignore the map entry rather |
| // than rejecting the config. |
| bool is_optional = 2; |
| } |