Skip to content

Commit 4bebf55

Browse files
sboulkourclaude
andcommitted
test: add e2e test for stripTrailingHostDot
Sends a request with a trailing dot in the Host header through a listener with ClientTrafficPolicy headers.host.stripTrailingHostDot enabled, and verifies the route matches and the backend receives the normalized Host header. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Salim Boulkour <salim.boulkour@algolia.com>
1 parent 9d10b3f commit 4bebf55

2 files changed

Lines changed: 115 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
apiVersion: gateway.envoyproxy.io/v1alpha1
2+
kind: ClientTrafficPolicy
3+
metadata:
4+
name: strip-trailing-host-dot-ctp
5+
namespace: gateway-conformance-infra
6+
spec:
7+
targetRefs:
8+
- group: gateway.networking.k8s.io
9+
kind: Gateway
10+
name: same-namespace
11+
headers:
12+
host:
13+
stripTrailingHostDot: true
14+
---
15+
apiVersion: gateway.networking.k8s.io/v1
16+
kind: HTTPRoute
17+
metadata:
18+
name: http-host-normalization
19+
namespace: gateway-conformance-infra
20+
spec:
21+
parentRefs:
22+
- name: same-namespace
23+
hostnames:
24+
- host-normalization.example.com
25+
rules:
26+
- matches:
27+
- path:
28+
type: PathPrefix
29+
value: /host-normalization
30+
backendRefs:
31+
- name: infra-backend-v1
32+
port: 8080
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright Envoy Gateway Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
// The full text of the Apache license is available in the LICENSE file at
4+
// the root of the repo.
5+
6+
//go:build e2e
7+
8+
package tests
9+
10+
import (
11+
"testing"
12+
13+
"k8s.io/apimachinery/pkg/types"
14+
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
15+
"sigs.k8s.io/gateway-api/conformance/utils/http"
16+
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
17+
"sigs.k8s.io/gateway-api/conformance/utils/suite"
18+
19+
"github.com/envoyproxy/gateway/internal/gatewayapi"
20+
"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
21+
)
22+
23+
func init() {
24+
ConformanceTests = append(ConformanceTests, HostNormalizationTest)
25+
}
26+
27+
var HostNormalizationTest = suite.ConformanceTest{
28+
ShortName: "HostNormalization",
29+
Description: "Strip the trailing dot from the Host header before route matching",
30+
Manifests: []string{"testdata/host-normalization.yaml"},
31+
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
32+
ns := "gateway-conformance-infra"
33+
routeNN := types.NamespacedName{Name: "http-host-normalization", Namespace: ns}
34+
gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
35+
gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gwapiv1.HTTPRoute{}, false, routeNN)
36+
37+
ancestorRef := gwapiv1.ParentReference{
38+
Group: gatewayapi.GroupPtr(gwapiv1.GroupName),
39+
Kind: gatewayapi.KindPtr(resource.KindGateway),
40+
Namespace: gatewayapi.NamespacePtr(gwNN.Namespace),
41+
Name: gwapiv1.ObjectName(gwNN.Name),
42+
}
43+
ClientTrafficPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "strip-trailing-host-dot-ctp", Namespace: ns}, suite.ControllerName, ancestorRef)
44+
45+
t.Run("host without trailing dot should match the route", func(t *testing.T) {
46+
expected := http.ExpectedResponse{
47+
Request: http.Request{
48+
Host: "host-normalization.example.com",
49+
Path: "/host-normalization",
50+
},
51+
Response: http.Response{
52+
StatusCodes: []int{200},
53+
},
54+
Namespace: ns,
55+
}
56+
57+
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expected)
58+
})
59+
60+
t.Run("host with trailing dot should be normalized and match the route", func(t *testing.T) {
61+
expected := http.ExpectedResponse{
62+
Request: http.Request{
63+
Host: "host-normalization.example.com.",
64+
Path: "/host-normalization",
65+
},
66+
// The trailing dot is stripped before routing, so the backend
67+
// receives the normalized Host header.
68+
ExpectedRequest: &http.ExpectedRequest{
69+
Request: http.Request{
70+
Host: "host-normalization.example.com",
71+
Path: "/host-normalization",
72+
},
73+
},
74+
Response: http.Response{
75+
StatusCodes: []int{200},
76+
},
77+
Namespace: ns,
78+
}
79+
80+
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expected)
81+
})
82+
},
83+
}

0 commit comments

Comments
 (0)