diff --git a/assets/agw-docs/pages/traffic-management/rewrite/host.md b/assets/agw-docs/pages/traffic-management/rewrite/host.md index 8731d4ae9..898598985 100644 --- a/assets/agw-docs/pages/traffic-management/rewrite/host.md +++ b/assets/agw-docs/pages/traffic-management/rewrite/host.md @@ -211,6 +211,77 @@ EOF } ``` +{{< version exclude-if="1.0.x,1.1.x,1.2.x,1.3.x,1.4.x,1.5.x,2.2.x" >}} +## Backend-specific host rewrites + +When a rule splits traffic between backends that expect different hosts, rewrite the host for one backend only. To do so, add the `URLRewrite` filter to the `backendRefs` entry of that backend instead of to the rule. Requests to the other backends in the rule keep their original host. + +1. Create an HTTPRoute that splits traffic on the `backend-host-rewrite.example` domain between the in-cluster httpbin app and the `httpbin.org` {{< reuse "/agw-docs/snippets/backend.md" >}} that you created in the [external service](#external-service-host-rewrites) section. Only the requests to `httpbin.org` are rewritten to the `httpbin.org` host. + ```yaml + kubectl apply -f- <}} + hostnames: + - backend-host-rewrite.example + rules: + - backendRefs: + - name: httpbin + port: 8000 + weight: 50 + - name: httpbin + kind: {{< reuse "/agw-docs/snippets/backend.md" >}} + group: agentgateway.dev + weight: 50 + filters: + - type: URLRewrite + urlRewrite: + hostname: "httpbin.org" + EOF + ``` + + |Setting|Description| + |--|--| + |`spec.rules.backendRefs.weight`| The share of requests that each backend gets. In this example, each backend gets half of the requests. | + |`spec.rules.backendRefs.filters.type`| The filter that applies only to the requests that the gateway forwards to this backend. In this example, the `URLRewrite` filter is used. The in-cluster httpbin backend has no filter, so its requests keep the `backend-host-rewrite.example` host. | + |`spec.rules.backendRefs.filters.urlRewrite.hostname`| The hostname that you want to rewrite to for the requests that the gateway forwards to this backend. | + +2. Send six requests to the `backend-host-rewrite.example` domain, and print the `Host` header that each backend received. Verify that the requests to the in-cluster httpbin app keep the `backend-host-rewrite.example` host, and that the requests to `httpbin.org` have the `httpbin.org` host. + + {{< tabs >}} + {{% tab name="Cloud Provider LoadBalancer" %}} + ```sh + for i in $(seq 1 6); do + curl -s http://$INGRESS_GW_ADDRESS:80/headers -H "host: backend-host-rewrite.example" | jq -c '.headers.Host' + done + ``` + {{% /tab %}} + {{% tab name="Port-forward for local testing" %}} + ```sh + for i in $(seq 1 6); do + curl -s localhost:8080/headers -H "host: backend-host-rewrite.example" | jq -c '.headers.Host' + done + ``` + {{% /tab %}} + {{< /tabs >}} + + Example output: The in-cluster httpbin app returns the host as a list, and `httpbin.org` returns it as a string. Because the gateway splits the traffic by weight, the order of your output differs. + ```console + ["backend-host-rewrite.example"] + "httpbin.org" + "httpbin.org" + ["backend-host-rewrite.example"] + "httpbin.org" + ["backend-host-rewrite.example"] + ``` +{{< /version >}} + ## Cleanup {{< reuse "agw-docs/snippets/cleanup.md" >}} @@ -221,5 +292,13 @@ kubectl delete httproute backend-rewrite -n httpbin kubectl delete {{< reuse "/agw-docs/snippets/backend.md" >}} httpbin -n httpbin ``` +{{< version exclude-if="1.0.x,1.1.x,1.2.x,1.3.x,1.4.x,1.5.x,2.2.x" >}} +If you created the backend-specific host rewrite, delete its HTTPRoute. + +```sh +kubectl delete httproute backend-host-rewrite -n httpbin +``` +{{< /version >}} + diff --git a/assets/agw-docs/pages/traffic-management/rewrite/path.md b/assets/agw-docs/pages/traffic-management/rewrite/path.md index 307b9df34..5e51e199b 100644 --- a/assets/agw-docs/pages/traffic-management/rewrite/path.md +++ b/assets/agw-docs/pages/traffic-management/rewrite/path.md @@ -497,7 +497,76 @@ EOF } ``` - +{{< version exclude-if="1.0.x,1.1.x,1.2.x,1.3.x,1.4.x,1.5.x,2.2.x" >}} +## Backend-specific path rewrites + +To rewrite the path for one backend only, add the `URLRewrite` filter to the `backendRefs` entry of that backend instead of to the rule. When the rule has more than one backend, requests to the other backends keep their original path. For an example that splits traffic between two backends, see [Backend-specific host rewrites]({{< link-hextra path="/documentation/traffic-management/rewrite/host/#backend-specific-host-rewrites" >}}). + +1. Create an HTTPRoute that rewrites the `/headers` prefix path to the `/anything` prefix path for the requests that the gateway forwards to the httpbin app on the `backend-path-rewrite.example` domain. + ```yaml + kubectl apply -f- <}} + hostnames: + - backend-path-rewrite.example + rules: + - matches: + - path: + type: PathPrefix + value: /headers + backendRefs: + - name: httpbin + port: 8000 + filters: + - type: URLRewrite + urlRewrite: + path: + type: ReplacePrefixMatch + replacePrefixMatch: /anything + EOF + ``` + + |Setting|Description| + |--|--| + |`spec.rules.matches`| The request to match. To use `ReplacePrefixMatch` in a backend filter, the rule must have exactly one match, and that match must be a `PathPrefix` match. Otherwise, the Kubernetes API server rejects the HTTPRoute when you apply it. | + |`spec.rules.backendRefs.filters.type`| The filter that applies only to the requests that the gateway forwards to this backend. In this example, the `URLRewrite` filter is used. | + |`spec.rules.backendRefs.filters.urlRewrite.path.type`| The type of HTTPPathModifier that you want to use. In this example, `ReplacePrefixMatch` is used, which replaces only the path prefix. Do not also add a `ReplacePrefixMatch` rewrite to the `filters` of the rule. The backend rewrite runs after the rule rewrite and cannot find the matched prefix in the rewritten path, so the request fails with a 500 HTTP response code. | + |`spec.rules.backendRefs.filters.urlRewrite.path.replacePrefixMatch`| The path prefix that you want to rewrite to. In this example, you replace the `/headers` prefix with the `/anything` prefix. | + +2. Send a request along the `/headers` path on the `backend-path-rewrite.example` domain. Verify that you get back a 200 HTTP response code and that your request is rewritten to the `/anything` path. + {{< tabs >}} + {{% tab name="Cloud Provider LoadBalancer" %}} + ```sh + curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: backend-path-rewrite.example:80" + ``` + {{% /tab %}} + {{% tab name="Port-forward for local testing" %}} + ```sh + curl -vi localhost:8080/headers -H "host: backend-path-rewrite.example" + ``` + {{% /tab %}} + {{< /tabs >}} + + Example output: + ```console {hl_lines=[3]} + ... + "origin": "10.244.0.31:44800", + "url": "http://backend-path-rewrite.example/anything", + "data": "", + "files": null, + "form": null, + "json": null + ... + ``` +{{< /version >}} + ## Cleanup {{< reuse "agw-docs/snippets/cleanup.md" >}} @@ -508,5 +577,10 @@ kubectl delete httproute backend-rewrite -n httpbin kubectl delete {{< reuse "/agw-docs/snippets/backend.md" >}} httpbin -n httpbin ``` +{{< version exclude-if="1.0.x,1.1.x,1.2.x,1.3.x,1.4.x,1.5.x,2.2.x" >}} +If you created the backend-specific path rewrite, delete its HTTPRoute. - +```sh +kubectl delete httproute backend-path-rewrite -n httpbin +``` +{{< /version >}}