• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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