Skip to content

Commit 6bf98d7

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. Signed-off-by: Salim Boulkour <salim.boulkour@algolia.com>
1 parent fc42045 commit 6bf98d7

18 files changed

Lines changed: 169 additions & 197 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
@@ -812,17 +812,20 @@ spec:
812812
description: Host enables managing how the Host/Authority header set
813813
by clients can be normalized.
814814
properties:
815-
stripPortMode:
815+
stripPort:
816816
description: |-
817-
StripPortMode determines how the port is stripped from the Host/Authority header
818-
before route matching.
819-
"Any" strips the port unconditionally, "Matching" strips it only when it matches
820-
the listener's port.
817+
StripPort determines whether the port is removed from the Host/Authority header
818+
before route matching. It maps to Envoy's strip_any_host_port, which strips the
819+
port unconditionally.
821820
If not set, no port stripping is performed (Envoy default).
822-
enum:
823-
- Any
824-
- Matching
825-
type: string
821+
822+
Stripping only the port that matches the listener port (Envoy's
823+
strip_matching_host_port) is intentionally not offered: Envoy compares against the
824+
Envoy listener port, which differs from the user-facing Gateway listener port (for
825+
example, a Gateway listener on port 80 is translated to an Envoy listener on port
826+
10080). Matching-port stripping would therefore be silently ineffective for the
827+
port clients actually use, so only unconditional stripping is exposed.
828+
type: boolean
826829
stripTrailingHostDot:
827830
description: |-
828831
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
@@ -811,17 +811,20 @@ spec:
811811
description: Host enables managing how the Host/Authority header set
812812
by clients can be normalized.
813813
properties:
814-
stripPortMode:
814+
stripPort:
815815
description: |-
816-
StripPortMode determines how the port is stripped from the Host/Authority header
817-
before route matching.
818-
"Any" strips the port unconditionally, "Matching" strips it only when it matches
819-
the listener's port.
816+
StripPort determines whether the port is removed from the Host/Authority header
817+
before route matching. It maps to Envoy's strip_any_host_port, which strips the
818+
port unconditionally.
820819
If not set, no port stripping is performed (Envoy default).
821-
enum:
822-
- Any
823-
- Matching
824-
type: string
820+
821+
Stripping only the port that matches the listener port (Envoy's
822+
strip_matching_host_port) is intentionally not offered: Envoy compares against the
823+
Envoy listener port, which differs from the user-facing Gateway listener port (for
824+
example, a Gateway listener on port 80 is translated to an Envoy listener on port
825+
10080). Matching-port stripping would therefore be silently ineffective for the
826+
port clients actually use, so only unconditional stripping is exposed.
827+
type: boolean
825828
stripTrailingHostDot:
826829
description: |-
827830
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
@@ -691,15 +691,13 @@ func translateHostSettings(hostSettings *egv1a1.HostSettings, httpIR *ir.HTTPLis
691691
if hostSettings == nil {
692692
return
693693
}
694-
if hostSettings.StripPortMode == nil && hostSettings.StripTrailingHostDot == nil {
694+
if hostSettings.StripPort == nil && hostSettings.StripTrailingHostDot == nil {
695695
return
696696
}
697697
httpIR.Host = &ir.HostSettings{
698+
StripPort: ptr.Deref(hostSettings.StripPort, false),
698699
StripTrailingHostDot: ptr.Deref(hostSettings.StripTrailingHostDot, false),
699700
}
700-
if hostSettings.StripPortMode != nil {
701-
httpIR.Host.StripPortMode = ir.StripPortMode(*hostSettings.StripPortMode)
702-
}
703701
}
704702

705703
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
@@ -403,13 +403,9 @@ func (t *Translator) addHCMToXDSListener(
403403
// Normalize the Host/Authority header if configured.
404404
// StripAnyHostPort uses the strip_port_mode oneof, so it must be assigned outside the
405405
// struct literal to avoid a typed-nil that silently breaks xDS translation.
406-
// StripMatchingHostPort is a standalone bool field (not part of the oneof).
407406
if irListener.Host != nil {
408-
switch irListener.Host.StripPortMode {
409-
case ir.StripPortModeAny:
407+
if irListener.Host.StripPort {
410408
mgr.StripPortMode = &hcmv3.HttpConnectionManager_StripAnyHostPort{StripAnyHostPort: true}
411-
case ir.StripPortModeMatching:
412-
mgr.StripMatchingHostPort = true
413409
}
414410
mgr.StripTrailingHostDot = irListener.Host.StripTrailingHostDot
415411
}

0 commit comments

Comments
 (0)