Support range based header matching for request routing. (#475)

v2 api changes: Use oneof to specify header match options, based on value(exact_match), regex or range.
The existing value and regex fields will be deprecated. Use the header_match_specfier oneof instead.

Add a new range.proto (envoy.type.v2) for the range type definition.
The SInt64Range message is defined in envoy.type.v2 range.proto.
It consists of start and end (inclusive, exclusive) sint64 values.

v1 api: Add a range_match object to the route headers json. Presence of this object indicates range based route match.

Example: For the below route config:
{
"prefix": "/",
"cluster": "PartitionB",
"name": "PartitionKey",
"range_match": { "start": 0, "end": 10}
}
In the incoming request, if the PartitionKey header value = 0, route match succeeds. Route match fails if the header value = 10, -10, "somestring".
This feature can be used for request routing with Service Fabric stateful services, to route to the desired partition with the [ranged partitioning scheme](https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-concepts-partitioning#ranged-partitioning-scheme)

Signed-off-by: Kavya Kotacherry <kavyako@microsoft.com>
pull/509/head
Kavya Kotacherry - MSFT 7 years ago committed by htuch
parent 5d5f29064a
commit 5d452340ed
  1. 1
      docs/BUILD
  2. 1
      docs/build.sh
  3. 27
      docs/root/api-v1/route_config/route.rst
  4. 1
      docs/root/api-v2/api.rst
  5. 8
      docs/root/api-v2/types/range.rst
  6. 2
      envoy/api/v2/route/BUILD
  7. 37
      envoy/api/v2/route/route.proto
  8. 14
      envoy/type/BUILD
  9. 15
      envoy/type/range.proto

@ -49,5 +49,6 @@ proto_library(
"//envoy/service/discovery/v2:ads",
"//envoy/service/load_stats/v2:lrs",
"//envoy/service/metrics/v2:metrics_service",
"//envoy/type:range",
],
)

@ -66,6 +66,7 @@ PROTO_RST="
/envoy/config/filter/network/rate_limit/v2/rate_limit/envoy/config/filter/network/rate_limit/v2/rate_limit.proto.rst
/envoy/config/filter/network/redis_proxy/v2/redis_proxy/envoy/config/filter/network/redis_proxy/v2/redis_proxy.proto.rst
/envoy/config/filter/network/tcp_proxy/v2/tcp_proxy/envoy/config/filter/network/tcp_proxy/v2/tcp_proxy.proto.rst
/envoy/type/range/envoy/type/range.proto.rst
"
# Dump all the generated RST so they can be added to PROTO_RST easily.

@ -338,7 +338,8 @@ Headers
{
"name": "...",
"value": "...",
"regex": "..."
"regex": "...",
"range_match": "..."
}
name
@ -361,6 +362,9 @@ regex
* The regex *\d{3}* does not match the value *1234*
* The regex *\d{3}* does not match the value *123.456*
:ref:`range_match <config_http_conn_man_route_table_range>`
*(optional, object)* Specifies the range that will be used for header matching.
.. attention::
Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 *Host*
@ -526,3 +530,24 @@ expose_headers
max_age
*(optional, string)* The content for the *access-control-max-age* header.
Value in seconds for how long the response to the preflight request can be cached.
.. _config_http_conn_man_route_table_range:
range_match
--------------
Specifies the int64 start and end of the range using half-open interval semantics [start, end).
Header route matching will be performed if the header's value lies within this range.
.. code-block:: json
{
"start": "...",
"end": "..."
}
start
*(required, integer)* start of the range (inclusive).
end
*(required, integer)* end of the range (exclusive).

@ -13,3 +13,4 @@ v2 API reference
http_routes/http_routes
config/filter/filter
common_messages/common_messages
types/range

@ -0,0 +1,8 @@
Types
=========
.. toctree::
:glob:
:maxdepth: 2
../type/range.proto

@ -9,6 +9,7 @@ api_proto_library(
deps = [
"//envoy/api/v2/auth",
"//envoy/api/v2/core:base",
"//envoy/type:range",
],
)
@ -18,5 +19,6 @@ api_go_proto_library(
deps = [
"//envoy/api/v2/auth:auth_go_proto",
"//envoy/api/v2/core:base_go_proto",
"//envoy/type:range_go_proto",
],
)

@ -5,6 +5,7 @@ option go_package = "route";
import "envoy/api/v2/core/base.proto";
import "envoy/api/v2/auth/auth.proto";
import "envoy/type/range.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
@ -815,6 +816,42 @@ message HeaderMatcher {
// * The regex *\d{3}* does not match the value *1234*
// * The regex *\d{3}* does not match the value *123.456*
google.protobuf.BoolValue regex = 3;
// [#not-implemented-hide:]
// Specifies how the header match will be performed to route the request.
// If header_match_specifier is absent, a request that has the
// :ref:`envoy_api_msg_route.HeaderMatcher.name` header will match, regardless of the header's
// value.
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. The regex grammar used in the value field is defined
// `here <http://en.cppreference.com/w/cpp/regex/ecmascript>`_.
//
// Examples:
//
// * The regex *\d{3}* matches the value *123*
// * The regex *\d{3}* does not match the value *1234*
// * The regex *\d{3}* does not match the value *123.456*
string regex_match = 5;
// [#not-implemented-hide:]
// 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"
envoy.type.Int64Range range_match = 6;
}
}
// Query parameter matching treats the query string of a request's :path header

@ -0,0 +1,14 @@
load("//bazel:api_build_system.bzl", "api_proto_library", "api_go_proto_library")
licenses(["notice"]) # Apache 2
api_proto_library(
name = "range",
srcs = ["range.proto"],
visibility = ["//visibility:public"],
)
api_go_proto_library(
name = "range",
proto = ":range",
)

@ -0,0 +1,15 @@
syntax = "proto3";
package envoy.type;
// [#protodoc-title: Range]
// Specifies the int64 start and end of the range using half-open interval semantics [start,
// end).
message Int64Range {
// start of the range (inclusive)
int64 start = 1;
// end of the range (exclusive)
int64 end = 2;
}
Loading…
Cancel
Save