diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 9066e9876fb..9e35cb00cc6 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -8,6 +8,7 @@ package gatewayapi import ( "fmt" "sort" + "strings" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -89,19 +90,29 @@ func (t *Translator) ProcessClientTrafficPolicies(clientTrafficPolicies []*egv1a policyMap[key].Insert(section) // Translate for listener matching section name + var err error for _, l := range gateway.listeners { if string(l.Name) == section { - t.translateClientTrafficPolicyForListener(&policy.Spec, l, xdsIR, infraIR) + err = t.translateClientTrafficPolicyForListener(&policy.Spec, l, xdsIR, infraIR) break } } - // Set Accepted=True - status.SetClientTrafficPolicyCondition(policy, - gwv1a2.PolicyConditionAccepted, - metav1.ConditionTrue, - gwv1a2.PolicyReasonAccepted, - "ClientTrafficPolicy has been accepted.", - ) + if err != nil { + status.SetClientTrafficPolicyCondition(policy, + gwv1a2.PolicyConditionAccepted, + metav1.ConditionFalse, + gwv1a2.PolicyReasonInvalid, + status.Error2ConditionMsg(err), + ) + } else { + // Set Accepted=True + status.SetClientTrafficPolicyCondition(policy, + gwv1a2.PolicyConditionAccepted, + metav1.ConditionTrue, + gwv1a2.PolicyReasonAccepted, + "ClientTrafficPolicy has been accepted.", + ) + } } } @@ -162,22 +173,32 @@ func (t *Translator) ProcessClientTrafficPolicies(clientTrafficPolicies []*egv1a policyMap[key].Insert(AllSections) // Translate sections that have not yet been targeted + var err error for _, l := range gateway.listeners { // Skip if section has already been targeted if s != nil && s.Has(string(l.Name)) { continue } - t.translateClientTrafficPolicyForListener(&policy.Spec, l, xdsIR, infraIR) + err = t.translateClientTrafficPolicyForListener(&policy.Spec, l, xdsIR, infraIR) } - // Set Accepted=True - status.SetClientTrafficPolicyCondition(policy, - gwv1a2.PolicyConditionAccepted, - metav1.ConditionTrue, - gwv1a2.PolicyReasonAccepted, - "ClientTrafficPolicy has been accepted.", - ) + if err != nil { + status.SetClientTrafficPolicyCondition(policy, + gwv1a2.PolicyConditionAccepted, + metav1.ConditionFalse, + gwv1a2.PolicyReasonInvalid, + status.Error2ConditionMsg(err), + ) + } else { + // Set Accepted=True + status.SetClientTrafficPolicyCondition(policy, + gwv1a2.PolicyConditionAccepted, + metav1.ConditionTrue, + gwv1a2.PolicyReasonAccepted, + "ClientTrafficPolicy has been accepted.", + ) + } } } @@ -265,7 +286,7 @@ func resolveCTPolicyTargetRef(policy *egv1a1.ClientTrafficPolicy, gateways []*Ga return gateway } -func (t *Translator) translateClientTrafficPolicyForListener(policySpec *egv1a1.ClientTrafficPolicySpec, l *ListenerContext, xdsIR XdsIRMap, infraIR InfraIRMap) { +func (t *Translator) translateClientTrafficPolicyForListener(policySpec *egv1a1.ClientTrafficPolicySpec, l *ListenerContext, xdsIR XdsIRMap, infraIR InfraIRMap) error { // Find IR irKey := irStringKey(l.gateway.Namespace, l.gateway.Name) // It must exist since we've already finished processing the gateways @@ -302,7 +323,9 @@ func (t *Translator) translateClientTrafficPolicyForListener(policySpec *egv1a1. translatePathSettings(policySpec.Path, httpIR) // Translate HTTP1 Settings - translateHTTP1Settings(policySpec.HTTP1, httpIR) + if err := translateHTTP1Settings(policySpec.HTTP1, httpIR); err != nil { + return err + } // enable http3 if set and TLS is enabled if httpIR.TLS != nil && policySpec.HTTP3 != nil { @@ -322,6 +345,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policySpec *egv1a1. // Translate TLS parameters translateListenerTLSParameters(policySpec.TLS, httpIR) } + return nil } func translateListenerTCPKeepalive(tcpKeepAlive *egv1a1.TCPKeepalive, httpIR *ir.HTTPListener) { @@ -394,14 +418,36 @@ func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, http httpIR.SuppressEnvoyHeaders = true } -func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTPListener) { +func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTPListener) error { if http1Settings == nil { - return + return nil } httpIR.HTTP1 = &ir.HTTP1Settings{ EnableTrailers: ptr.Deref(http1Settings.EnableTrailers, false), PreserveHeaderCase: ptr.Deref(http1Settings.PreserveHeaderCase, false), } + if http1Settings.HTTP10 != nil { + var defaultHost *string + if ptr.Deref(http1Settings.HTTP10.UseDefaultHost, false) { + for _, hostname := range httpIR.Hostnames { + if !strings.Contains(hostname, "*") { + // make linter happy + theHost := hostname + defaultHost = &theHost + break + } + } + if defaultHost == nil { + return fmt.Errorf("can't set http10 default host on listener with only wildcard hostnames") + } + } + // If useDefaultHost was set, then defaultHost will have the hostname to use. + // If no good hostname was found, an error would have been returned. + httpIR.HTTP1.HTTP10 = &ir.HTTP10Settings{ + DefaultHost: defaultHost, + } + } + return nil } func translateListenerTLSParameters(tlsParams *egv1a1.TLSSettings, httpIR *ir.HTTPListener) { diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml new file mode 100644 index 00000000000..8d54877593d --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml @@ -0,0 +1,73 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-1 + spec: + http1: + http10: {} + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-1 + namespace: envoy-gateway +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-2 + spec: + http1: + http10: + useDefaultHost: true + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-2 + namespace: envoy-gateway +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-3 + spec: + http1: + http10: + useDefaultHost: true + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-3 + namespace: envoy-gateway +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + - name: http-2 + protocol: HTTP + hostname: www.example.com + port: 8080 + allowedRoutes: + namespaces: + from: Same + - name: http-3 + protocol: HTTP + port: 8081 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml new file mode 100644 index 00000000000..07640e3a50e --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http10.out.yaml @@ -0,0 +1,238 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1-section-http-1 + namespace: envoy-gateway + spec: + http1: + http10: {} + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + status: + conditions: + - lastTransitionTime: null + message: ClientTrafficPolicy has been accepted. + reason: Accepted + status: "True" + type: Accepted +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1-section-http-2 + namespace: envoy-gateway + spec: + http1: + http10: + useDefaultHost: true + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-2 + status: + conditions: + - lastTransitionTime: null + message: ClientTrafficPolicy has been accepted. + reason: Accepted + status: "True" + type: Accepted +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1-section-http-3 + namespace: envoy-gateway + spec: + http1: + http10: + useDefaultHost: true + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-3 + status: + conditions: + - lastTransitionTime: null + message: Can't set http10 default host on listener with only wildcard hostnames + reason: Invalid + status: "False" + type: Accepted +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: Same + hostname: www.example.com + name: http-2 + port: 8080 + protocol: HTTP + - allowedRoutes: + namespaces: + from: Same + name: http-3 + port: 8081 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-3 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http-1 + ports: + - containerPort: 10080 + name: http-1 + protocol: HTTP + servicePort: 80 + - address: null + name: envoy-gateway/gateway-1/http-2 + ports: + - containerPort: 8080 + name: http-2 + protocol: HTTP + servicePort: 8080 + - address: null + name: envoy-gateway/gateway-1/http-3 + ports: + - containerPort: 8081 + name: http-3 + protocol: HTTP + servicePort: 8081 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + http1: + http10: {} + isHTTP2: false + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + - address: 0.0.0.0 + hostnames: + - www.example.com + http1: + http10: + defaultHost: www.example.com + isHTTP2: false + name: envoy-gateway/gateway-1/http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8080 + - address: 0.0.0.0 + hostnames: + - '*' + http1: {} + isHTTP2: false + name: envoy-gateway/gateway-1/http-3 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8081 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index fcbd8c1fde9..c16104d7c0a 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -355,8 +355,17 @@ type BackendWeights struct { // HTTP1Settings provides HTTP/1 configuration on the listener. // +k8s:deepcopy-gen=true type HTTP1Settings struct { - EnableTrailers bool `json:"enableTrailers,omitempty" yaml:"enableTrailers,omitempty"` - PreserveHeaderCase bool `json:"preserveHeaderCase,omitempty" yaml:"preserveHeaderCase,omitempty"` + EnableTrailers bool `json:"enableTrailers,omitempty" yaml:"enableTrailers,omitempty"` + PreserveHeaderCase bool `json:"preserveHeaderCase,omitempty" yaml:"preserveHeaderCase,omitempty"` + HTTP10 *HTTP10Settings `json:"http10,omitempty" yaml:"http10,omitempty"` +} + +// HTTP10Settings provides HTTP/1.0 configuration on the listener. +// +k8s:deepcopy-gen=true +type HTTP10Settings struct { + // defaultHost is set to the default host that should be injected for HTTP10. If the hostname shouldn't + // be set, then defaultHost will be nil + DefaultHost *string `json:"defaultHost,omitempty" yaml:"defaultHost,omitempty"` } // HTTPRoute holds the route information associated with the HTTP Route diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 0381491c31d..00415ccf1d6 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -489,9 +489,34 @@ func (in *GlobalRateLimit) DeepCopy() *GlobalRateLimit { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTP10Settings) DeepCopyInto(out *HTTP10Settings) { + *out = *in + if in.DefaultHost != nil { + in, out := &in.DefaultHost, &out.DefaultHost + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP10Settings. +func (in *HTTP10Settings) DeepCopy() *HTTP10Settings { + if in == nil { + return nil + } + out := new(HTTP10Settings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTP1Settings) DeepCopyInto(out *HTTP1Settings) { *out = *in + if in.HTTP10 != nil { + in, out := &in.HTTP10, &out.HTTP10 + *out = new(HTTP10Settings) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP1Settings. @@ -598,7 +623,7 @@ func (in *HTTPListener) DeepCopyInto(out *HTTPListener) { if in.HTTP1 != nil { in, out := &in.HTTP1, &out.HTTP1 *out = new(HTTP1Settings) - **out = **in + (*in).DeepCopyInto(*out) } } diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index 126534794fd..14c70f6bd85 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -24,6 +24,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" + "k8s.io/utils/ptr" "github.com/envoyproxy/gateway/internal/ir" ) @@ -328,7 +329,7 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. (args.timeout.HTTP.MaxConnectionDuration != nil || args.timeout.HTTP.ConnectionIdleTimeout != nil)) || (args.circuitBreaker != nil && args.circuitBreaker.MaxRequestsPerConnection != nil) - requiresHTTP1Options := args.http1Settings != nil && (args.http1Settings.EnableTrailers || args.http1Settings.PreserveHeaderCase) + requiresHTTP1Options := args.http1Settings != nil && (args.http1Settings.EnableTrailers || args.http1Settings.PreserveHeaderCase || args.http1Settings.HTTP10 != nil) if !(requiresCommonHTTPOptions || requiresHTTP1Options || requiresHTTP2Options) { return nil @@ -363,7 +364,7 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. // If translation requires HTTP2 enablement or HTTP1 trailers, set appropriate setting // Default to http1 otherwise // TODO: If the cluster is TLS enabled, use AutoHTTPConfig instead of ExplicitHttpConfig - // so that when ALPN is supported enabling trailers doesn't force HTTP/1.1 + // so that when ALPN is supported then enabling http1 options doesn't force HTTP/1.1 switch { case requiresHTTP2Options: protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ @@ -386,6 +387,10 @@ func buildTypedExtensionProtocolOptions(args *xdsClusterArgs) map[string]*anypb. }, } } + if args.http1Settings.HTTP10 != nil { + http1opts.AcceptHttp_10 = true + http1opts.DefaultHostForHttp_10 = ptr.Deref(args.http1Settings.HTTP10.DefaultHost, "") + } protocolOptions.UpstreamProtocolOptions = &httpv3.HttpProtocolOptions_ExplicitHttpConfig_{ ExplicitHttpConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig{ ProtocolConfig: &httpv3.HttpProtocolOptions_ExplicitHttpConfig_HttpProtocolOptions{ diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 6d2e9da6d0d..665f2e2e7b3 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -46,7 +46,7 @@ func http1ProtocolOptions(opts *ir.HTTP1Settings) *corev3.Http1ProtocolOptions { if opts == nil { return nil } - if !opts.EnableTrailers && !opts.PreserveHeaderCase { + if !opts.EnableTrailers && !opts.PreserveHeaderCase && opts.HTTP10 == nil { return nil } // If PreserveHeaderCase is true and EnableTrailers is false then setting the EnableTrailers field to false @@ -65,6 +65,10 @@ func http1ProtocolOptions(opts *ir.HTTP1Settings) *corev3.Http1ProtocolOptions { }, } } + if opts.HTTP10 != nil { + r.AcceptHttp_10 = true + r.DefaultHostForHttp_10 = ptr.Deref(opts.HTTP10.DefaultHost, "") + } return r } diff --git a/internal/xds/translator/testdata/in/xds-ir/http10.yaml b/internal/xds/translator/testdata/in/xds-ir/http10.yaml new file mode 100644 index 00000000000..47f57a04422 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http10.yaml @@ -0,0 +1,21 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "foo.com" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + http1: + http10: + defaultHost: "foo.com" + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml new file mode 100644 index 00000000000..5fe5a91e3ed --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http10.clusters.yaml @@ -0,0 +1,21 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + httpProtocolOptions: + acceptHttp10: true + defaultHostForHttp10: foo.com diff --git a/internal/xds/translator/testdata/out/xds-ir/http10.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http10.endpoints.yaml new file mode 100644 index 00000000000..3b3f2d09076 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http10.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml new file mode 100644 index 00000000000..890a2c5437c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http10.listeners.yaml @@ -0,0 +1,36 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + httpProtocolOptions: + acceptHttp10: true + defaultHostForHttp10: foo.com + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + statPrefix: http + upgradeConfigs: + - upgradeType: websocket + useRemoteAddress: true + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http10.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http10.routes.yaml new file mode 100644 index 00000000000..2734c7cc42a --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http10.routes.yaml @@ -0,0 +1,12 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 7ce9f41e195..3ca7583456f 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -260,6 +260,9 @@ func TestTranslateXds(t *testing.T) { { name: "ext-auth", }, + { + name: "http10", + }, } for _, tc := range testCases {