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/discovery/v2:ads",
"//envoy/service/load_stats/v2:lrs", "//envoy/service/load_stats/v2:lrs",
"//envoy/service/metrics/v2:metrics_service", "//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/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/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/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. # Dump all the generated RST so they can be added to PROTO_RST easily.

@ -338,7 +338,8 @@ Headers
{ {
"name": "...", "name": "...",
"value": "...", "value": "...",
"regex": "..." "regex": "...",
"range_match": "..."
} }
name 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 *1234*
* The regex *\d{3}* does not match the value *123.456* * 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:: .. attention::
Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 *Host* Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 *Host*
@ -526,3 +530,24 @@ expose_headers
max_age max_age
*(optional, string)* The content for the *access-control-max-age* header. *(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. 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 http_routes/http_routes
config/filter/filter config/filter/filter
common_messages/common_messages 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 = [ deps = [
"//envoy/api/v2/auth", "//envoy/api/v2/auth",
"//envoy/api/v2/core:base", "//envoy/api/v2/core:base",
"//envoy/type:range",
], ],
) )
@ -18,5 +19,6 @@ api_go_proto_library(
deps = [ deps = [
"//envoy/api/v2/auth:auth_go_proto", "//envoy/api/v2/auth:auth_go_proto",
"//envoy/api/v2/core:base_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/core/base.proto";
import "envoy/api/v2/auth/auth.proto"; import "envoy/api/v2/auth/auth.proto";
import "envoy/type/range.proto";
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.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 *1234*
// * The regex *\d{3}* does not match the value *123.456* // * The regex *\d{3}* does not match the value *123.456*
google.protobuf.BoolValue regex = 3; 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 // 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