Skip to content

Commit fb1b4ff

Browse files
committed
api: replace host.stripPortMode enum with host.stripPort bool
Drop the stripPortMode (Any|Matching) enum on ClientTrafficPolicy's host section and replace it with a stripPort *bool that maps to Envoy's strip_any_host_port (unconditional stripping). The Matching mode mapped to strip_matching_host_port, which compares the Host header port against the Envoy listener port. Since a Gateway listener on e.g. port 80 is translated to an Envoy listener on port 10080, Matching never strips the port clients actually use, so it was silently ineffective. As discussed in the PR review, only unconditional stripping is exposed, expressed as a boolean per maintainer suggestion. Regenerated CRDs, deepcopy, helm snapshots, docs and golden testdata, and renamed the strip-port-matching gatewayapi test to strip-port. The release note is now a fragment under release-notes/current/new_features/ following the split-release-notes workflow (#9312). Signed-off-by: Salim Boulkour <salim.boulkour@algolia.com>
1 parent a12f92f commit fb1b4ff

18 files changed

Lines changed: 169 additions & 196 deletions

api/v1alpha1/hostsettings_types.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,23 @@
55

66
package v1alpha1
77

8-
// StripPortMode determines how the port is stripped from the Host/Authority header
9-
// before route matching.
10-
// +kubebuilder:validation:Enum=Any;Matching
11-
type StripPortMode string
12-
13-
const (
14-
// StripPortModeAny strips the port from the Host/Authority header unconditionally.
15-
StripPortModeAny StripPortMode = "Any"
16-
// StripPortModeMatching strips the port from the Host/Authority header only when it
17-
// matches the listener's port.
18-
StripPortModeMatching StripPortMode = "Matching"
19-
)
20-
218
// HostSettings provides settings that manage how the incoming Host/Authority header
229
// set by clients is normalized.
2310
type HostSettings struct {
24-
// StripPortMode determines how the port is stripped from the Host/Authority header
25-
// before route matching.
26-
// "Any" strips the port unconditionally, "Matching" strips it only when it matches
27-
// the listener's port.
11+
// StripPort determines whether the port is removed from the Host/Authority header
12+
// before route matching. It maps to Envoy's strip_any_host_port, which strips the
13+
// port unconditionally.
2814
// If not set, no port stripping is performed (Envoy default).
2915
//
16+
// Stripping only the port that matches the listener port (Envoy's
17+
// strip_matching_host_port) is intentionally not offered: Envoy compares against the
18+
// Envoy listener port, which differs from the user-facing Gateway listener port (for
19+
// example, a Gateway listener on port 80 is translated to an Envoy listener on port
20+
// 10080). Matching-port stripping would therefore be silently ineffective for the
21+
// port clients actually use, so only unconditional stripping is exposed.
22+
//
3023
// +optional
31-
StripPortMode *StripPortMode `json:"stripPortMode,omitempty"`
24+
StripPort *bool `json:"stripPort,omitempty"`
3225
// StripTrailingHostDot determines if the trailing dot of the host should be removed
3326
// from the Host/Authority header before any processing of the request.
3427
// This affects the upstream host header as well. Without this option, incoming requests

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -820,17 +820,20 @@ spec:
820820
description: Host enables managing how the Host/Authority header set
821821
by clients can be normalized.
822822
properties:
823-
stripPortMode:
823+
stripPort:
824824
description: |-
825-
StripPortMode determines how the port is stripped from the Host/Authority header
826-
before route matching.
827-
"Any" strips the port unconditionally, "Matching" strips it only when it matches
828-
the listener's port.
825+
StripPort determines whether the port is removed from the Host/Authority header
826+
before route matching. It maps to Envoy's strip_any_host_port, which strips the
827+
port unconditionally.
829828
If not set, no port stripping is performed (Envoy default).
830-
enum:
831-
- Any
832-
- Matching
833-
type: string
829+
830+
Stripping only the port that matches the listener port (Envoy's
831+
strip_matching_host_port) is intentionally not offered: Envoy compares against the
832+
Envoy listener port, which differs from the user-facing Gateway listener port (for
833+
example, a Gateway listener on port 80 is translated to an Envoy listener on port
834+
10080). Matching-port stripping would therefore be silently ineffective for the
835+
port clients actually use, so only unconditional stripping is exposed.
836+
type: boolean
834837
stripTrailingHostDot:
835838
description: |-
836839
StripTrailingHostDot determines if the trailing dot of the host should be removed

charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -819,17 +819,20 @@ spec:
819819
description: Host enables managing how the Host/Authority header set
820820
by clients can be normalized.
821821
properties:
822-
stripPortMode:
822+
stripPort:
823823
description: |-
824-
StripPortMode determines how the port is stripped from the Host/Authority header
825-
before route matching.
826-
"Any" strips the port unconditionally, "Matching" strips it only when it matches
827-
the listener's port.
824+
StripPort determines whether the port is removed from the Host/Authority header
825+
before route matching. It maps to Envoy's strip_any_host_port, which strips the
826+
port unconditionally.
828827
If not set, no port stripping is performed (Envoy default).
829-
enum:
830-
- Any
831-
- Matching
832-
type: string
828+
829+
Stripping only the port that matches the listener port (Envoy's
830+
strip_matching_host_port) is intentionally not offered: Envoy compares against the
831+
Envoy listener port, which differs from the user-facing Gateway listener port (for
832+
example, a Gateway listener on port 80 is translated to an Envoy listener on port
833+
10080). Matching-port stripping would therefore be silently ineffective for the
834+
port clients actually use, so only unconditional stripping is exposed.
835+
type: boolean
833836
stripTrailingHostDot:
834837
description: |-
835838
StripTrailingHostDot determines if the trailing dot of the host should be removed

internal/gatewayapi/clienttrafficpolicy.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -846,15 +846,13 @@ func translateHostSettings(hostSettings *egv1a1.HostSettings, httpIR *ir.HTTPLis
846846
if hostSettings == nil {
847847
return
848848
}
849-
if hostSettings.StripPortMode == nil && hostSettings.StripTrailingHostDot == nil {
849+
if hostSettings.StripPort == nil && hostSettings.StripTrailingHostDot == nil {
850850
return
851851
}
852852
httpIR.Host = &ir.HostSettings{
853+
StripPort: ptr.Deref(hostSettings.StripPort, false),
853854
StripTrailingHostDot: ptr.Deref(hostSettings.StripTrailingHostDot, false),
854855
}
855-
if hostSettings.StripPortMode != nil {
856-
httpIR.Host.StripPortMode = ir.StripPortMode(*hostSettings.StripPortMode)
857-
}
858856
}
859857

860858
func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout, error) {

internal/gatewayapi/testdata/clienttrafficpolicy-host-strip-port-matching.in.yaml

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
clientTrafficPolicies:
2+
- apiVersion: gateway.envoyproxy.io/v1alpha1
3+
kind: ClientTrafficPolicy
4+
metadata:
5+
namespace: envoy-gateway
6+
name: target-gateway-1
7+
spec:
8+
host:
9+
stripPort: true
10+
targetRef:
11+
group: gateway.networking.k8s.io
12+
kind: Gateway
13+
name: gateway-1
14+
gateways:
15+
- apiVersion: gateway.networking.k8s.io/v1
16+
kind: Gateway
17+
metadata:
18+
namespace: envoy-gateway
19+
name: gateway-1
20+
spec:
21+
gatewayClassName: envoy-gateway-class
22+
listeners:
23+
- name: http-1
24+
protocol: HTTP
25+
port: 80
26+
allowedRoutes:
27+
namespaces:
28+
from: Same

internal/gatewayapi/testdata/clienttrafficpolicy-host-strip-port-matching.out.yaml renamed to internal/gatewayapi/testdata/clienttrafficpolicy-host-strip-port.out.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ clientTrafficPolicies:
66
namespace: envoy-gateway
77
spec:
88
host:
9-
stripPortMode: Matching
9+
stripPort: true
1010
targetRef:
1111
group: gateway.networking.k8s.io
1212
kind: Gateway
@@ -119,7 +119,7 @@ xdsIR:
119119
- address: 0.0.0.0
120120
externalPort: 80
121121
host:
122-
stripPortMode: Matching
122+
stripPort: true
123123
hostnames:
124124
- '*'
125125
metadata:

internal/ir/xds.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -591,23 +591,12 @@ type PathSettings struct {
591591
EscapedSlashesAction PathEscapedSlashAction `json:"escapedSlashesAction" yaml:"escapedSlashesAction"`
592592
}
593593

594-
// StripPortMode determines how the port is stripped from the Host/Authority header.
595-
type StripPortMode string
596-
597-
const (
598-
// StripPortModeAny strips the port from the Host/Authority header unconditionally.
599-
StripPortModeAny StripPortMode = "Any"
600-
// StripPortModeMatching strips the port from the Host/Authority header only when it
601-
// matches the listener's port.
602-
StripPortModeMatching StripPortMode = "Matching"
603-
)
604-
605594
// HostSettings holds configuration for Host/Authority header normalization
606595
// +k8s:deepcopy-gen=true
607596
type HostSettings struct {
608-
// StripPortMode determines how the port is stripped from the Host/Authority header.
609-
// An empty value means no port stripping is performed.
610-
StripPortMode StripPortMode `json:"stripPortMode,omitempty" yaml:"stripPortMode,omitempty"`
597+
// StripPort strips the port from the Host/Authority header unconditionally
598+
// (Envoy's strip_any_host_port). A false value means no port stripping is performed.
599+
StripPort bool `json:"stripPort,omitempty" yaml:"stripPort,omitempty"`
611600
// StripTrailingHostDot strips the trailing dot from the Host/Authority header before processing.
612601
StripTrailingHostDot bool `json:"stripTrailingHostDot,omitempty" yaml:"stripTrailingHostDot,omitempty"`
613602
}

internal/xds/translator/listener.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,13 +404,9 @@ func (t *Translator) addHCMToXDSListener(
404404
// Normalize the Host/Authority header if configured.
405405
// StripAnyHostPort uses the strip_port_mode oneof, so it must be assigned outside the
406406
// struct literal to avoid a typed-nil that silently breaks xDS translation.
407-
// StripMatchingHostPort is a standalone bool field (not part of the oneof).
408407
if irListener.Host != nil {
409-
switch irListener.Host.StripPortMode {
410-
case ir.StripPortModeAny:
408+
if irListener.Host.StripPort {
411409
mgr.StripPortMode = &hcmv3.HttpConnectionManager_StripAnyHostPort{StripAnyHostPort: true}
412-
case ir.StripPortModeMatching:
413-
mgr.StripMatchingHostPort = true
414410
}
415411
mgr.StripTrailingHostDot = irListener.Host.StripTrailingHostDot
416412
}

0 commit comments

Comments
 (0)