-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add per-httpproxy http-version support #5802
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,6 +18,10 @@ import ( | |||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
) | ||||||
|
||||||
// HttpVersion is an alias to enforce validation | ||||||
// +kubebuilder:validation:Enum=h2;http/1.1 | ||||||
type HttpVersion string | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use the following casing for the Go type/field:
Suggested change
|
||||||
|
||||||
// HTTPProxySpec defines the spec of the CRD. | ||||||
type HTTPProxySpec struct { | ||||||
// Virtualhost appears at most once. If it is present, the object is considered | ||||||
|
@@ -40,6 +44,11 @@ type HTTPProxySpec struct { | |||||
// is given precedence over this field. | ||||||
// +optional | ||||||
IngressClassName string `json:"ingressClassName,omitempty"` | ||||||
|
||||||
// HttpVersions specify the http versions to offer for this HTTPProxy. | ||||||
// If empty, the DefaultHTTPVersions from v1alpha1.EnvoyConfig will be used. | ||||||
// It is ignored when TCPProxy is set. | ||||||
HttpVersions []HttpVersion `json:"httpVersions,omitempty"` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should move at least under the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think even if we should name it alpnProtos and not httpVersions? because it is only for the offered alpnProtos, so even if h2 is not offered in alpn proto, users can still use h2 with prior knowledge and it is still supported. also if permitInsecure is true, then h2c is supported as well. so maybe being more specific about it in the field name, helps people understand the actual behavior. WDYT? @therealak12 @skriss There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for moving this under VirtualHost |
||||||
} | ||||||
|
||||||
// Include describes a set of policies that can be applied to an HTTPProxy in a namespace. | ||||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Adds HttpVersions field to HTTPProxy spec. The field is used to specify ALPNProtocols on the corresponding tls context. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -263,6 +263,7 @@ func (p *HTTPProxyProcessor) computeHTTPProxy(proxy *contour_api_v1.HTTPProxy) { | |
svhost.Secret = sec | ||
svhost.MinTLSVersion = minTLSVer | ||
svhost.MaxTLSVersion = maxTLSVer | ||
svhost.HttpVersions = p.getSortedHttpVersions(proxy) | ||
|
||
// Check if FallbackCertificate && ClientValidation are both enabled in the same vhost | ||
if tls.EnableFallbackCertificate && tls.ClientValidation != nil { | ||
|
@@ -1473,6 +1474,21 @@ func (p *HTTPProxyProcessor) GlobalAuthorizationContext() map[string]string { | |
return nil | ||
} | ||
|
||
// getSortedHttpVersions returns and empty slice or ["h2", "http/1.1"] or ["http/1.1"]. | ||
// This is done to conform with how envoy expects AlpnProtocols in tlsv3.CommonTlsContext. | ||
func (p *HTTPProxyProcessor) getSortedHttpVersions(proxy *contour_api_v1.HTTPProxy) []string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be nice to reduce the duplication between this new method, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do agree to move |
||
proxyHttpVersions := proxy.Spec.HttpVersions | ||
if len(proxyHttpVersions) == 0 { | ||
return nil | ||
} | ||
for _, httpVersion := range proxyHttpVersions { | ||
if httpVersion == "h2" { | ||
return []string{"h2", "http/1.1"} | ||
} | ||
} | ||
return []string{"http/1.1"} | ||
} | ||
|
||
// expandPrefixMatches adds new Routes to account for the difference | ||
// between prefix replacement when matching on '/foo' and '/foo/'. | ||
// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -502,7 +502,11 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { | |
|
||
filters = envoy_v3.Filters(cm) | ||
|
||
alpnProtos = envoy_v3.ProtoNamesForVersions(cfg.DefaultHTTPVersions...) | ||
if len(vh.HttpVersions) != 0 { | ||
alpnProtos = vh.HttpVersions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case where the vhost specifies HTTP versions, I think we can also use the virtual host's HTTP versions for the HTTPConnectionManager's codec, above, since it's specific to the vhost. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment still needs to be addressed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. I'll do when there's an agreement on this. |
||
} else { | ||
alpnProtos = envoy_v3.ProtoNamesForVersions(cfg.DefaultHTTPVersions...) | ||
} | ||
} else { | ||
filters = envoy_v3.Filters(envoy_v3.TCPProxy(listener.Name, vh.TCPProxy, cfg.newSecureAccessLog())) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we already have these constants defined in the ContourConfiguration struct (in v1alpha1) and the Contour config file, let's use the same values for them here for consistency:
Yes, this will then require a translation to the Envoy-accepted values, but we already have code for this in
cmd/contour/parseDefaultHTTPVersions
andinternal/envoy/v3/ProtoNamesForVersions
that we should be able to reuse, possibly with some refactoring required.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
parseDefaultHTTPVersions
converts from["HTTP/1.1", "HTTP/2"]
toHTTPVersionType
.The
ProtoNamesForVersions
function converts fromHTTPVersionType
to["http/1.1", "h2"]
.Note that the desired format for Envoy configuration is ["http/1.1", "h2"]. So, why use the ["HTTP/1.1", "HTTP/2"] format at all instead of directly using ["http/1.1", "h2"]? 😅
Additionally, those functions cannot be easily imported since they're private, or importing them leads to import cycles unless we move them into a util-like package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment already answers my question. So thanks. I'll refactor.