- Notifications
You must be signed in to change notification settings - Fork 142
feat(interceptor): add HTTP/2 h2c support for cleartext connections #1394
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
base: main
Are you sure you want to change the base?
feat(interceptor): add HTTP/2 h2c support for cleartext connections #1394
Conversation
Enable HTTP/2 cleartext (h2c) protocol support for non-TLS connections in the interceptor proxy server. This allows AWS Application Load Balancers and other clients to communicate with the interceptor using HTTP/2 over plain HTTP. When tlsConfig is nil, the handler is wrapped with h2c.NewHandler to support both HTTP/2 prior knowledge and HTTP/1.1 connections. TLS connections remain unchanged and continue to support native HTTP/2 over TLS. This change enables the use of appProtocol: kubernetes.io/h2c on Kubernetes Services, which instructs the AWS Load Balancer Controller to create target groups with ProtocolVersion: HTTP2 for improved performance and efficiency. Changes: - Wrap non-TLS handlers with h2c.NewHandler in pkg/http/server.go - Add golang.org/x/net/http2 dependency for h2c support - Add comprehensive test coverage for both HTTP/1.1 and HTTP/2 h2c - Maintain backwards compatibility with HTTP/1.1 clients Fixes: Enables HTTP/2 h2c support from ALB to interceptor pods Signed-off-by: Starlight Romero <28881133+starlightromero@users.noreply.github.com>
|
| Status | Scanner | Total (0) | ||||
|---|---|---|---|---|---|---|
| Open Source Security | 0 | 0 | 0 | 0 | See details |
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.
linkvt left a comment
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.
Hi @starlightromero ,
thanks for the PR! I left a few comments but also think that we would benefit from a written design in an issue here in the repo - at least in my opinion.
I'm not a maintainer of this project though.
| if tlsConfig == nil { | ||
| h2s := &http2.Server{} | ||
| hdl = h2c.NewHandler(hdl, h2s) | ||
| } |
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.
golang has HTTP2 support for server and clients in its standard library, they added it quite recently: https://go.dev/doc/go1.24#nethttppkgnethttp
I would prefer using that over the extended standard library as they already plan to deprecate the golang.org/x/net/http2/client subpackage: golang/go#72039
| Handler: hdl, | ||
| Addr: addr, | ||
| TLSConfig: tlsConfig, | ||
| } |
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.
How do we handle:
- HTTP1 connections to services responding with h2c
- h2c connections to services responding with HTTP1?
| DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { | ||
| // Use standard dialer for h2c (cleartext HTTP/2) | ||
| return net.Dial(network, addr) | ||
| }, |
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.
Is this actually needed/used during an non HTTPS request?
| ctx, cancel := context.WithCancel(context.Background()) | ||
| defer cancel() | ||
| | ||
| serverAddr := "127.0.0.1:18888" |
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.
I think we should not expect a specific port on a system to be free for us to use during a test. I know that the httptest package can pick a selected port, not sure if we can use it here, but maybe there is another way to get a port thats always free to use.
| @@ -0,0 +1,90 @@ | |||
| package http | |||
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.
IMO we should have e2e tests covering the different scenarios here (client uses http1/h2c, user application supports http1/h2c/both) as unit tests would not cover all cases.
Description
This PR adds HTTP/2 cleartext (h2c) protocol support to the interceptor proxy server, enabling AWS Application Load Balancers and other clients to communicate using HTTP/2 over plain HTTP.
Changes
golang.org/x/net/http2for h2c supportpkg/http/h2c_test.gofor both HTTP/1.1 and HTTP/2 h2cMotivation
When using the AWS Load Balancer Controller Gateway API implementation, setting
appProtocol: kubernetes.io/h2con a Kubernetes Service instructs the controller to create ALB target groups withProtocolVersion: HTTP2. However, the KEDA HTTP Add-on interceptor did not support h2c, causing health checks and traffic to fail.This change enables:
appProtocol: kubernetes.io/h2con Kubernetes ServicesHow It Works
The implementation wraps non-TLS handlers with
h2c.NewHandler, which automatically:TLS connections remain unchanged and continue to use native HTTP/2 over TLS.
Testing
TestHTTP2H2CSupportvalidates both HTTP/1.1 and HTTP/2 h2c functionalityChecklist
make test)Fixes: Enables HTTP/2 h2c support from ALB to interceptor pods