`.
+You can use the following recommendations to increase routing performance:
-{{site.base_gateway}} 3.0.x or later ships with a new router. The new router can use regex expression capture groups to describe routes using a domain-specific language called Expressions. Expressions can describe routes or paths as patterns using regular expressions. For more information about how to configure the router using Expressions, see [How to configure routes using expressions](https://docs.konghq.com/gateway/latest/key-concepts/routes/expressions/).
+* In `expressions` mode, we recommend putting more likely matched Routes before (as in, higher priority) those that are less frequently matched.
+* Regular expressions in Routes use more resources to evaluate than simple prefixes. In installations with thousands of Routes, replacing a regular expression with simple prefix can improve throughput and latency of {{site.base_gateway}}. If a regex must be used because an exact path match must be performed, using the [expressions router](/gateway/routing/expressions/) will significantly improve {{site.base_gateway}}’s performance in this case.
## Schema
diff --git a/app/_includes/components/feature_table.html b/app/_includes/components/feature_table.html
index a566f0edf..0d82b2797 100644
--- a/app/_includes/components/feature_table.html
+++ b/app/_includes/components/feature_table.html
@@ -26,13 +26,13 @@
{% for column in include.columns %}
{% assign v = row[column.key] %}
-
+ |
{% if v == true %}
{% include icon_true.html %}
{% elsif v == false %}
{% include icon_false.html %}
{% else %}
- {{v}}
+ {{v | liquify | markdown}}
{% endif %}
|
{% endfor %}
diff --git a/app/_includes/info_box/concept.html b/app/_includes/info_box/concept.html
index 2d3791d77..abe08e1cb 100644
--- a/app/_includes/info_box/concept.html
+++ b/app/_includes/info_box/concept.html
@@ -8,4 +8,8 @@
{% if page.related_resources %}
{% include info_box/sections/related_resources.html %}
+{% endif %}
+
+{% if page.min_version %}
+{% include info_box/sections/min_version.html min_version=page.min_version %}
{% endif %}
\ No newline at end of file
diff --git a/app/gateway/routing/expressions.md b/app/gateway/routing/expressions.md
index 9edd79471..9a12216b4 100644
--- a/app/gateway/routing/expressions.md
+++ b/app/gateway/routing/expressions.md
@@ -1,7 +1,7 @@
---
title: Expressions router
-description: "{{site.base_gateway}} includes a rule-based engine using a domain-specific expressions language."
+description: "The expressions router is a collection of Routes that are all evaluated against incoming requests until a match can be found."
content_type: reference
layout: reference
@@ -12,159 +12,444 @@ products:
related_resources:
- text: Route entity
url: /gateway/entities/route/
- - text: Routing in {{site.base_gateway}}
- url: /gateway/routing/
- text: Expressions repository
url: https://github.com/Kong/atc-router
+min_version:
+ gateway: '3.0'
+
breadcrumbs:
- /gateway/
- - /gateway/routing/
----
-
-{{ page.description | liquify }} Expressions can be used to perform tasks such as defining
-complex routing logic.
-This guide is a reference for the expressions language and explains how it can be used.
-
-## About the expressions language
-
-The expressions language is a strongly typed Domain-Specific Language (DSL)
-that allows you to define comparison operations on various input data.
-The results of the comparisons can be combined with logical operations, which allows complex routing logic to be written while ensuring good runtime matching performance.
-### Key concepts
-
-* **Field:** The field contains value extracted from the incoming request. For example,
- the request path or the value of a header field. The field value could also be absent
- in some cases. An absent field value will always cause the predicate to yield `false`
- no matter the operator. The field always displays to the left of the predicate.
-* **Constant value:** The constant value is what the field is compared to based on the
- provided operator. The constant value always displays to the right of the predicate.
-* **Operator:** An operator defines the desired comparison action to be performed on the field
- against the provided constant value. The operator always displays in the middle of the predicate,
- between the field and constant value.
-* **Predicate:** A predicate compares a field against a pre-defined value using the provided operator and
- returns `true` if the field passed the comparison or `false` if it didn't.
-* **Route:** A route is one or more predicates combined together with logical operators.
-* **Router:** A router is a collection of routes that are all evaluated against incoming
- requests until a match can be found.
-* **Priority:** The priority is a positive integer that defines the order of evaluation of the router.
- The bigger the priority, the sooner a route will be evaluated. In the case of duplicate
- priority values between two routes in the same router, their order of evaluation is undefined.
-
-![Structure of a predicate](https://docs.konghq.com/assets/images/products/gateway/reference/expressions-language/predicate.png)
-
-A predicate is structured like the following:
+faqs:
+ - q: When should I use the expressions router in place of (or alongside) the traditional router?
+ a: We recommend using the expressions router if you are running {{site.base_gateway}} 3.0.x or later. After enabling expressions, traditional match fields on the Route object (such as `paths` and `methods`) remain configurable. You may specify Expressions in the new `expression` field. However, these cannot be configured simultaneously with traditional match fields. Additionally, a new `priority` field, used in conjunction with the expression field, allows you to specify the order of evaluation for Expression Routes.
+---
+The expressions router is a collection of [Routes](/gateway/entities/route/) that are all evaluated against incoming requests until a match can be found. This allows for more complex routing logic than the traditional router and ensures good runtime matching performance.
+
+You can do the following with the expressions router:
+* Prefix-based path matching
+* Regex-based path matching that is less of a performance burden than the traditional router
+* Case insensitive path matching
+* Match by header value
+* Regex captures
+* Match by source IP and destination port
+* Match by SNI (for TLS Routes)
+
+## Enable the expressions router
+
+In your `kong.conf` file, set `router_flavor = expressions` and restart your {{site.base_gateway}}. Once the router is enabled, you can use the `expression` parameter when you're creating a Route to specify the Routes.
+
+## How requests are routed with the expressions router
+
+At runtime, {{site.base_gateway}} builds two separate routers for the HTTP and Stream (TCP, TLS, UDP) subsystem. When a request/connection comes in, {{site.base_gateway}} looks at which field your configured Routes require,
+and supplies the value of these fields to the router execution context.
+Routes are inserted into each router with the appropriate `priority` field set. The priority is a positive integer that defines the order of evaluation of the router. The bigger the priority, the sooner a Route will be evaluated. In the case of duplicate priority values between two Routes in the same router, their order of evaluation is undefined. The router is
+updated incrementally as configured Routes change.
+
+As soon as a Route yields a match, the router stops matching and the matched Route is used to process the current request/connection.
+
+For example, if you have the following three Routes:
+
+* **Route A**
+ ```
+ expression: http.path ^= "/foo" && http.host == "example.com"
+ priority: 100
+ ```
+* **Route B**
+ ```
+ expression: http.path ^= "/foo"
+ priority: 50
+ ```
+* **Route C**
+ ```
+ expression: http.path ^= "/"
+ priority: 10
+ ```
+
+And you have the following incoming request:
```
-http.path ^= "/foo/bar"
+http.path:"/foo/bar"
+http.post:"konghq.com"
```
-This predicate example has the following structure:
-* `http.path`: Field
-* `^=`: Operator
-* `"/foo/bar"`: Constant value
+The router does the following:
-## How routes are executed
+1. The router checks Route A first because it has the highest priority. It doesn't match the incoming request, so the router checks the Route with the next highest priority.
+1. Route B has the next highest priority, so the router checks this one second. It matches the request, so the router doesn't check Route C.
-At runtime, {{site.base_gateway}} builds two separate routers for the HTTP and Stream (TCP, TLS, UDP) subsystem.
-Routes are inserted into each router with the appropriate `priority` field set. The router is
-updated incrementally as configured routes change.
+## Performance considerations
-When a request/connection comes in, {{site.base_gateway}} looks at which field your configured routes require,
-and supplies the value of these fields to the router execution context. This is evaluated against
-the configured routes in descending order (routes with a higher `priority` number are evaluated first).
+This section explains how to optimize the expressions you write to get the most performance out of the routing engine.
-As soon as a route yields a match, the router stops matching and the matched route is used to process the current request/connection.
+### Number of routes
-![Router matching flow](https://docs.konghq.com/assets/images/products/gateway/reference/expressions-language/router-matching-flow.png)
+#### Route matching priority order
-> _**Figure 1:**_ Diagram of how {{site.base_gateway}} executes routes. The diagram shows that {{site.base_gateway}} selects the route that both matches the expression and then selects the matching route with the highest priority.
+Expressions routes are always evaluated in the descending `priority` order they were defined.
+Therefore, it is helpful to put more likely matched routes before (as in, higher priority)
+less frequently matched routes.
-## Expression router examples (HTTP)
-### Prefix based path matching
+The following examples show how you would prioritize two routes based on if they were likely to be matched or not.
-Prefix based path matching is one of the most commonly used methods for routing. For example, if you want to match HTTP requests that have a path starting with `/foo/bar`, you can write the following route:
+Example route 1:
+```
+expression: http.path == "/likely/matched/request/path"
+priority: 100
+```
+Example route 2:
```
-http.path ^= "/foo/bar"
+expression: http.path == "/unlikely/matched/request/path"
+priority: 50
```
-### Regex based path matching
+It's also best to reduce the number of `Route` entities created by leveraging the
+logical combination capability of the expressions language.
+
+#### Combining routes
-If you prefer to match a HTTP requests path against a regex, you can write the following route:
+If multiple routes result in the same `Service` and `Plugin` config being used,
+they should be combined into a single expression `Route` with the `||` logical or operator. By combining routes into a single expression, this results in fewer `Route` objects created and better performance.
+Example route 1:
```
-http.path ~ r#"/foo/bar/\d+"#
+service: example-service
+expression: http.path == "/hello"
```
-### Case insensitive path matching
+Example route 2:
+```
+service: example-service
+expression: http.path == "/world"
+```
-If you want to ignore case when performing the path match, use the `lower()` modifier on the field
-to ensure it always returns a lowercase value:
+These two routes can instead be combined as:
```
-lower(http.path) == "/foo/bar"
+service: example-service
+expression: http.path == "/hello" || http.path == "/world"
```
-This will match requests with a path of `/foo/bar` and `/FOO/bAr`, for example.
+### Regular expressions usage
-### Match by header value
+Regular expressions (regexes) are powerful tool that can be used to match strings based on
+very complex criteria. Unfortunately, this has also made them more expensive to
+evaluate at runtime and hard to optimize. Therefore, there are some common
+scenarios where regex usage can be eliminated, resulting in significantly
+better matching performance.
-If you want to match incoming requests by the value of header `X-Foo`, do the following:
+When performing exact matches (non-prefix matching) of a request path, use the `==` operator
+instead of regex.
+**Faster performance example:**
```
-http.headers.x_foo ~ r#"bar\d"#
+http.path == "/foo/bar"
```
-If there are multiple header values for `X-Foo` and the client sends more than
-one `X-Foo` header with different value, the above example will ensure **each** instance of the
-value will match the regex `r#"bar\d"#`. This is called "all" style matching, meaning each instance
-of the field value must pass the comparison for the predicate to return `true`. This is the default behavior.
-
-If you do not want this behavior, you can turn on "any" style of matching which returns
-`true` for the predicate as soon as any of the values pass the comparison:
-
+**Slower performance example:**
```
-any(http.headers.x_foo) ~ r#"bar\d"#
+http.path ~ r#"^/foo/bar$"#
```
-This will return `true` as soon as any value of `http.headers.x_foo` matches regex `r#"bar\d"#`.
-
-Different transformations can be chained together. The following is also a valid use case
-that performs case-insensitive matching:
+When performing exact matches with the `/` optional slash at the end, it is tempting to write
+regexes. However, this is completely unnecessary with the expressions language.
+**Faster performance example:**
```
-any(lower(http.headers.x_foo)) ~ r#"bar\d"#
+http.path == "/foo/bar" || http.path == "/foo/bar/"
```
-### Regex captures
-
-You can define regex capture groups in any regex operation which will be made available
-later for plugins to use. Currently, this is only supported with the `http.path` field:
-
+**Slower performance example:**
```
-http.path ~ r#"/foo/(?P.+)"#
+http.path ~ r#"^/foo/?$"#
```
-The matched value of `component` will be made available later to plugins such as
-[Request Transformer Advanced](https://docs.konghq.com/hub/kong-inc/request-transformer-advanced/how-to/templates/).
+## Expressions router reference
-## Expression router examples (TCP, TLS, UDP)
+This reference explains the different configurable entities for the expressions router.
-### Match by source IP and destination port
+### Expressions formatting
-```
-net.src.ip in 192.168.1.0/24 && net.dst.port == 8080
-```
+Each Route contains one or more predicates combined with logical operators, which {{site.base_gateway}} uses to match requests with Routes.
-This matches all clients in the `192.168.1.0/24` subnet and the destination port (which is listened to by Kong)
-is `8080`. IPv6 addresses are also supported.
-
-### Match by SNI (for TLS routes)
+A predicate is the basic unit of expressions code which takes the following form:
```
-tls.sni =^ ".example.com"
+http.path ^= "/foo/bar"
```
-This matches all TLS connections with the `.example.com` SNI ending.
+This predicate example has the following structure:
+* `http.path`: Field
+* `^=`: Operator
+* `"/foo/bar"`: Constant value
+
+Predicates are made up of smaller units that you can configure:
+
+| Object | Description | Example |
+|--------|-------------|---------|
+| Field | The field contains value extracted from the incoming request. For example, the request path or the value of a header field. The field value could also be absent in some cases. An absent field value will always cause the predicate to yield `false` no matter the operator. The field always displays to the left of the predicate. | `http.path` |
+| Constant value | The constant value is what the field is compared to based on the provided operator. The constant value always displays to the right of the predicate. | `"/foo/bar"` |
+| Operator | An operator defines the desired comparison action to be performed on the field against the provided constant value. The operator always displays in the middle of the predicate, between the field and constant value. | `^=` |
+| Predicate | A predicate compares a field against a pre-defined value using the provided operator and returns `true` if the field passed the comparison or `false` if it didn't. | `http.path ^= "/foo/bar"` |
+
+### Field and constant value types
+
+Types define what you can use for a predicate's field and constant value. Expressions language is strongly typed. Operations are only performed
+if such an operation makes sense in regard to the actual type of field and constant.
+
+Type conversion at runtime is not supported, either explicitly or implicitly. Types
+are always known at the time a route is parsed. An error is returned
+if the operator cannot be performed on the provided field and constant.
+
+The expressions language currently supports the following types:
+
+
+
+{% feature_table %}
+item_title: Object
+columns:
+ - title: Description
+ key: description
+ - title: Field type
+ key: field_type
+ - title: Constant type
+ key: constant_type
+features:
+ - title: |
+ `String`
+ description: |
+ A string value, always in valid UTF-8. They can be defined with string literal that looks like `"content"`. You can also use the following escape sequences:
+ * `\n`: Newline character
+ * `\r`: Carriage return character
+ * `\t`: Horizontal tab character
+ * `\\`: The `\` character
+ * `\"`: The `"` character
+ field_type: true
+ constant_type: true
+ - title: |
+ `IpCidr`
+ description: |
+ Range of IP addresses in CIDR format. Can be either IPv4 (`net.src.ip in 192.168.1.0/24`) or IPv6 (`net.src.ip in fd00::/8`). The expressions parser rejects any CIDR literal where the host portion contains any non-zero bits. This means that `192.168.0.1/24` won't pass the parser check because the intention of the author is unclear.
+ field_type: false
+ constant_type: true
+ - title: |
+ `IpAddr`
+ description: |
+ A single IP address in IPv4 Dot-decimal notation (`net.src.ip == 192.168.1.1`), or the standard IPv6 Address Format (`net.src.ip == fd00::1`). Can be either IPv4 or IPv6.
+ field_type: true
+ constant_type: true
+ - title: |
+ `Int`
+ description: |
+ A 64-bit signed integer. There is only one integer type in expressions. All integers are signed 64-bit integers. Integer literals can be written as `12345`, `-12345`, or in hexadecimal format, such as `0xab12ff`, or in octet format like `0751`.
+ field_type: true
+ constant_type: true
+ - title: |
+ `Regex`
+ description: |
+ Regex are written as `String` literals, but they are parsed when the `~` regex operator is present and checked for validity according to the [Rust `regex` crate syntax](https://docs.rs/regex/latest/regex/#syntax). For example, in the following predicate, the constant is parsed as a regex: `http.path ~ r#"/foo/bar/.+"#`
+ field_type: false
+ constant_type: true
+{% endfeature_table %}
+
+
+
+
+In addition, expressions also supports one composite type, `Array`. Array types are written as `Type[]`.
+For example: `String[]`, `Int[]`. Currently, arrays can only be present in field values. They are used in
+case one field could contain multiple values. For example, `http.headers.x` or `http.queries.x`.
+
+#### Matching fields
+
+The following table describes the available matching fields, as well as their associated type when using an expressions based router.
+
+
+
+{% feature_table %}
+item_title: Type
+columns:
+ - title: Type
+ key: type
+ - title: Available in HTTP Subsystem
+ key: http_subsystem
+ - title: Available in Stream Subsystem
+ key: stream_subsystem
+ - title: Description
+ key: description
+features:
+ - title: |
+ `net.protocol`
+ type: String
+ http_subsystem: true
+ stream_subsystem: true
+ description: |
+ Protocol of the route. Roughly equivalent to the `protocols` field on the `Route` entity. **Note:** Configured `protocols` on the `Route` entity are always added to the top level of the generated route but additional constraints can be provided by using the `net.protocol` field directly inside the expression.
+ - title: |
+ `tls.sni`
+ type: String
+ http_subsystem: true
+ stream_subsystem: true
+ description: |
+ If the connection is over TLS, the `server_name` extension from the ClientHello packet.
+ - title: |
+ `http.method`
+ type: String
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ The method of the incoming HTTP request. (for example, `"GET"` or `"POST"`)
+ - title: |
+ `http.host`
+ type: String
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ The `Host` header of the incoming HTTP request.
+ - title: |
+ `http.path`
+ type: String
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ The normalized request path according to rules defined in [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-6). This field value does **not** contain any query parameters that might exist.
+ - title: |
+ `http.path.segments.`
+ type: String
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ A path segment extracted from the incoming (normalized) `http.path` with zero-based index. For example, for request path `"/a/b/c/"` or `"/a/b/c"`, `http.path.segments.1` will return `"b"`.
+ - title: |
+ `http.path.segments._`
+ type: String
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ Path segments extracted from the incoming (normalized) `http.path` within the given closed interval joined by `/`. Indexes are zero-based. For example, for request path `"/a/b/c/"` or `"/a/b/c"`, `http.path.segments.0_1` will return `"a/b"`.
+ - title: |
+ `http.path.segments.len`
+ type: Int
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ Number of segments from the incoming (normalized) `http.path`. For example, for request path `"/a/b/c/"` or `"/a/b/c"`, `http.path.segments.len` will return `3`.
+ - title: |
+ `http.headers.`
+ type: String[]
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ The value(s) of request header ``. **Note:** The header name is always normalized to the underscore and lowercase form, so `Foo-Bar`, `Foo_Bar`, and `fOo-BAr` all become values of the `http.headers.foo_bar` field.
+ - title: |
+ `http.queries.`
+ type: String[]
+ http_subsystem: true
+ stream_subsystem: false
+ description: |
+ The value(s) of query parameter ``.
+ - title: |
+ `net.src.ip`
+ type: IpAddr
+ http_subsystem: true
+ stream_subsystem: true
+ description: |
+ IP address of the client.
+ - title: |
+ `net.src.port`
+ type: Int
+ http_subsystem: true
+ stream_subsystem: true
+ description: |
+ The port number used by the client to connect.
+ - title: |
+ `net.dst.ip`
+ type: IpAddr
+ http_subsystem: true
+ stream_subsystem: true
+ description: |
+ Listening IP address where {{site.base_gateway}} accepts the incoming connection.
+ - title: |
+ `net.dst.port`
+ type: Int
+ http_subsystem: true
+ stream_subsystem: true
+ description: |
+ Listening port number where {{site.base_gateway}} accepts the incoming connection.
+{% endfeature_table %}
+
+
+
+### Operators
+
+An operator defines the desired comparison action to be performed on the field against the provided constant value. The operator always displays in the middle of the predicate, between the field and constant value.
+
+The expressions language supports a rich set of operators that can be performed on various data types.
+
+| Operator | Name | Description |
+|----------------|-----------------------|--------------------------------------------------------------------------------------|
+| `==` | Equals | Field value is equal to the constant value |
+| `!=` | Not equals | Field value does not equal the constant value |
+| `~` | Regex match | Field value matches regex |
+| `^=` | Prefix match | Field value starts with the constant value |
+| `=^` | Postfix match | Field value ends with the constant value |
+| `>=` | Greater than or equal | Field value is greater than or equal to the constant value |
+| `>` | Greater than | Field value is greater than the constant value |
+| `<=` | Less than or equal | Field value is less than or equal to the constant value |
+| `<` | Less than | Field value is less than the constant value |
+| `in` | In | Field value is inside the constant value. This operator is used with `IpAddr` and `IpCidr` types to perform an efficient IP list check. For example, `net.src.ip in 192.168.0.0/24` will only return `true` if the value of `net.src.ip` is within `192.168.0.0/24`. |
+| `not in` | Not in | Field value is not inside the constant value. This operator is used with `IpAddr` and `IpCidr` types to perform an efficient IP list check. For example, `net.src.ip in 192.168.0.0/24` will only return `true` if the value of `net.src.ip` is within `192.168.0.0/24`. |
+| `contains` | Contains | Field value contains the constant value. This operator is used to check the existence of a string inside another string. For example, `http.path contains "foo"` will return `true` if `foo` can be found anywhere inside `http.path`. This will match a `http.path` that looks like `/foo`, `/abc/foo`, or `/xfooy`, for example. |
+| `&&` | And | Returns `true` if **both** expressions on the left and right side evaluates to `true` |
+| `||` | Or | Returns `true` if **any** expressions on the left and right side evaluates to `true` | |
+| `(Expression)` | Parenthesis | Groups expressions together to be evaluated first |
+| `!` | Not | Negates the result of a parenthesized expression. **Note:** The `!` operator can only be used with parenthesized expression like `!(foo == 1)`, it **cannot** be used with a bare predicate like `! foo == 1` |
+
+### Allowed type and operator combinations
+
+Depending on the field type, only certain content types and operators are supported.
+
+| Field type | Supported content types and their supported operators |
+|------------|-------------------------------------------------------|
+| `String` | * `String`: `==`, `!=`, `~`, `^=`, `=^`, `contains`
* `Regex`: `~` |
+| `IpAddr` | * `IpCidr`: `in`, `not in`
* `IpAddr`: `==` |
+| `Int` | `Int`: `==`, `!=`, `>=`, `>`, `<=`, `<` |
+| `Expression` | `Regex`: `&&`, `||` |
+
+
+{:.note}
+> **Notes:**
+ * The `~` operator is described as supporting both `String ~ String` and `String ~ Regex`.
+ In reality, `Regex` constant values can only be written as `String` on the right hand side.
+ The presence of `~` operators treats the string value as a regex.
+ Even with the `~` operator, `String` escape rules described previously still apply and it
+ is almost always easier to use raw string literals for the `~` operator.
+ * The `~` operator does not automatically anchor the regex to the beginning of the input.
+ Meaning `http.path ~ r#"/foo/\d"#` could match a path like `/foo/1` or `/some/thing/foo/1`.
+ If you want to match from the beginning of the string (anchoring the regex), then you must
+ manually specify it with the `^` meta-character. For example, `http.path ~ r#"^/foo/\d"#`.
+ * When performing IP address-related comparisons with `==`, `in`, or `not in`, different families of
+ address types for the field and constant value will always cause the predicate to return `false` at
+ runtime.
+
+## Example expressions
+
+### HTTP examples
+
+| Name | Example expression | Description |
+|------|--------------------|-------------|
+| Prefix based path matching | `http.path ^= "/foo/bar"` | Matches HTTP requests that have a path starting with `/foo/bar` |
+| Regex based path matching | `http.path ~ r#"/foo/bar/\d+"#` | N/A |
+| Case insensitive path matching | `lower(http.path) == "/foo/bar"` | Ignores case when performing the path match. |
+| Match by header value ("all" style matching) | `http.headers.x_foo ~ r#"bar\d"#` | If there are multiple header values for `X-Foo` and the client sends more than one `X-Foo` header with different values, the above example will ensure **each** instance of the value will match the regex `r#"bar\d"#`. This is called "all" style matching. |
+| Match by header value ("any" style matching) | `any(http.headers.x_foo) ~ r#"bar\d"#` | Returns `true` for the predicate as soon as any of the values pass the comparison. Can be combined with other transformations, like `lower()`. |
+| Regex captures | `http.path ~ r#"/foo/(?P.+)"#` | You can define regex capture groups in any regex operation which will be made available later for plugins to use. Currently, this is only supported with the `http.path` field. The matched value of `component` will be made available later to plugins such as [Request Transformer Advanced](/plugins/request-transformer-advanced/). |
+
+### TCP, TLS, and UDP examples
+
+| Name | Example expression | Description |
+|------|--------------------|-------------|
+| Match by source IP and destination port | `net.src.ip in 192.168.1.0/24 && net.dst.port == 8080` | This matches all clients in the `192.168.1.0/24` subnet and the destination port (which is listened to by {{site.base_gateway}}) is `8080`. IPv6 addresses are also supported. |
+| Match by SNI (for TLS routes) | `tls.sni =^ ".example.com"` | This matches all TLS connections with the `.example.com` SNI ending. |
+
diff --git a/app/gateway/routing/index.md b/app/gateway/routing/index.md
deleted file mode 100644
index 8e5810cc5..000000000
--- a/app/gateway/routing/index.md
+++ /dev/null
@@ -1,117 +0,0 @@
----
-title: Routing in {{site.base_gateway}}
-
-description: This page explains how routing works in {{site.base_gateway}}.
-
-content_type: reference
-layout: reference
-
-products:
- - gateway
-
-related_resources:
- - text: Route entity
- url: /gateway/entities/route/
- - text: Expressions router
- url: /gateway/routing/expressions/
-
-breadcrumbs:
- - /gateway/
----
-
-## How requests are routed
-
-For each incoming request, {{site.base_gateway}} must determine which
-service gets to handle it based on the routes that are defined. With
-release 3.0, {{site.base_gateway}} introduced a router that can be
-running in two modes: the `traditional_compat` mode, which is
-configured like prior releases, and the `expressions` mode which uses
-a new configuration scheme. We recommend that new deployments use
-the expressions router as it is more powerful and expressive.
-
-The default mode of the router is `traditional_compat` and the
-following sections describe how it operates. `traditional_compat`
-mode is designed to behave like the router in versions before
-{{site.base_gateway}} 3.x. For a description of the `expressions` mode, see
-[How to Configure Routes using Expressions](/gateway/routing/expressions/).
-
-In general, the router orders all defined routes by their priority and
-uses the highest priority matching route to handle a request. If there
-are multiple matching routes with the same priority, it is not defined
-which of the matching routes will be used and {{site.base_gateway}}
-will use either of them according to how its internal data structures
-are organized.
-
-If a route contains prefix or regular expression paths, the priority
-of the route will be calculated separately for each of the paths and
-requests will be routed accordingly.
-
-In `traditional_compat` mode, the priority of a route is determined as
-follows, by the order of descending significance:
-
-1. Priority points
-2. Wildcard hosts
-3. Header count
-4. Regular expressions and prefix paths
-
-### Priority points
-
-For the presence of each of a route's `methods`, `host`, `headers`,
-and `snis`, a "priority point" will be added to the route. The number
-of "priority points" determines the overall order in which the routes
-will be considered. Routes with a higher "priority point" values will
-be considered before those with lower values. This means that if one
-route has `methods` defined, and second one has `methods` and
-`headers` defined, the second one will be considered before the first
-one.
-
-### Wildcard hosts
-
-Among the routes with the same "priority point" value, those that have
-any wildcard host specification will be considered after routes that
-don't have any wildcard host (or no host) specified.
-
-### Header count
-
-The resulting groups are sorted so the routes with a higher number of
-specified headers have higher priority than those with a lower number
-of headers.
-
-## Regular expressions and prefix paths
-
-Within the resulting groups of routes with equal priority, the router
-sorts the routes as follows:
-
- - Routes that have a regular expression path are considered first and
- are ordered by their `regex_priority` value. Routes with a higher
- `regex_priority` are considered before routes with lower
- `regex_priority` values.
- - Routes that have no regular expression path are ordered by the
- length of their paths. Routes with longer paths are considered
- before routes with shorter paths.
-
-For a route with multiple paths, each path will be considered
-separately for priority determination. Effectively, this means that
-separate routes exists for each of the paths.
-
-## Regular expressions
-
-Regular expressions used in routes use more resources to evaluate than
-simple prefix routes. If many regular expressions must be evaluated
-to route a request, the latency introduced by {{site.base_gateway}}
-can suffer and its CPU usage can increase. In installations with
-thousands of routes, replacing regular expression routes by simple
-prefix routes can improve throughput and latency of
-{{site.base_gateway}}. If regex must be used because an exact
-path match must be performed, using the [expressions router](/gateway/routing/expressions/)
-will significantly improve {{site.base_gateway}}'s performance in this case.
-
-Starting with version 3.0, {{site.base_gateway}} uses the regular
-expression engine shipped with the [Rust](https://docs.rs/regex/latest/regex/) programming language if the
-router is operating in `expressions` or `traditional_compatible` mode.
-Prior versions used the
-[PCRE library](https://www.pcre.org/original/doc/html/pcrepattern.html)
-to evaluate regular expression. While the two engines are largely
-compatible, subtle differences exist between the two. Refer to
-the documentation pertinent to the engine that you are using if you
-have problems getting regular expression routes to work.
diff --git a/app/gateway/traffic-control/proxying.md b/app/gateway/traffic-control/proxying.md
new file mode 100644
index 000000000..7b88a6a65
--- /dev/null
+++ b/app/gateway/traffic-control/proxying.md
@@ -0,0 +1,33 @@
+---
+title: Proxying with {{site.base_gateway}}
+
+description: "Proxying is when {{site.base_gateway}} matches an HTTP request with a [registered route](/gateway/entities/route/) and forwards the request."
+
+content_type: reference
+layout: reference
+
+products:
+ - gateway
+
+related_resources:
+ - text: Route entity
+ url: /gateway/entities/route/
+ - text: Router Expressions language
+ url: /gateway/routing/expressions/
+ - text: Expressions repository
+ url: https://github.com/Kong/atc-router
+
+breadcrumbs:
+ - /gateway/
+---
+
+@todo
+
+
\ No newline at end of file
diff --git a/tools/track-docs-changes/config/sources.yml b/tools/track-docs-changes/config/sources.yml
index d856cd68b..e062ef0ad 100644
--- a/tools/track-docs-changes/config/sources.yml
+++ b/tools/track-docs-changes/config/sources.yml
@@ -46,11 +46,21 @@ app/_gateway_entities/service.md:
- app/_src/gateway/key-concepts/services.md
app/_gateway_entities/target.md:
- app/_src/gateway/key-concepts/services.md
+ - app/_src/gateway/get-started/load-balancing.md
+ - app/_src/gateway/key-concepts/upstreams.md
+ - app/_src/gateway/how-kong-works/load-balancing.md
app/_gateway_entities/upstream.md:
- app/_src/gateway/key-concepts/upstreams.md
+ - app/_src/gateway/how-kong-works/load-balancing.md
+ - app/_src/gateway/how-kong-works/health-checks.md
app/_gateway_entities/workspace.md:
- app/_src/gateway/kong-manager/workspaces.md
- app/_src/gateway/kong-enterprise/workspaces.md
+app/_gateway_entities/route.md:
+ - app/_src/gateway/how-kong-works/routing-traffic.md
+ - app/_src/gateway/key-concepts/routes/index.md
+app/_gateway_entities/upstream.md:
+ - app/_src/gateway/key-concepts/upstreams.md
app/_gateway_entities/event_hooks.md:
- app/_src/gateway/latest/kong-enterprise/event-hooks.md
@@ -126,8 +136,6 @@ app/gateway/rate-limiting/strategies.md:
app/gateway/rate-limiting/window-types.md:
- app/_hub/kong-inc/rate-limiting-advanced/overview/_index.md
- app/_hub/kong-inc/rate-limiting/overview/_index.md
-app/gateway/routing/expressions.md:
- - app/_src/gateway/reference/expressions-language/index.md
app/gateway/routing/index.md:
- app/_src/gateway/key-concepts/routes/index.md
app/plugins/deployment-options.md:
@@ -136,6 +144,18 @@ app/plugins/protocols.md:
- app/hub/plugins/compatibility/index.md
app/plugins/scopes.md:
- app/hub/plugins/compatibility/index.md
+
+# traffic control
+app/gateway/traffic-control/proxy.md:
+ - app/_src/gateway/how-kong-works/routing-traffic.md
+ - app/_includes/md/admin-listen.md
+app/gateway/routing/expressions.md:
+ - app/_src/gateway/reference/expressions-language/index.md
+ - app/_src/gateway/key-concepts/routes/expressions.md
+ - app/_src/gateway/reference/expressions-language/language-references.md
+ - app/_src/gateway/reference/expressions-language/performance.md
+app/gateway/routing/expressions-router-examples.md:
+ - app/_src/gateway/reference/expressions-language/index.md
app/gateway/networking/dns-config-reference.md:
- app/_src/gateway/production/networking/dns-considerations.md