Skip to content

Commit

Permalink
feat: Add support for HTTP/1.0 and HTTP/0.9 (envoyproxy#2577)
Browse files Browse the repository at this point in the history
* feat: Add support for HTTP/1.0 and HTTP/0.9

Signed-off-by: Lior Okman <lior.okman@sap.com>

* Make the linter happy

Signed-off-by: Lior Okman <lior.okman@sap.com>

---------

Signed-off-by: Lior Okman <lior.okman@sap.com>
  • Loading branch information
liorokman authored Feb 9, 2024
1 parent 53c9758 commit 5acc233
Show file tree
Hide file tree
Showing 13 changed files with 531 additions and 26 deletions.
86 changes: 66 additions & 20 deletions internal/gatewayapi/clienttrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package gatewayapi
import (
"fmt"
"sort"
"strings"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -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.",
)
}
}
}

Expand Down Expand Up @@ -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.",
)
}
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
73 changes: 73 additions & 0 deletions internal/gatewayapi/testdata/clienttrafficpolicy-http10.in.yaml
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 5acc233

Please sign in to comment.