Skip to content

Conversation

WeidiDeng
Copy link
Member

Golang 1.24 introduced a new type that can be used to specify the versions of http caddy can handle. Now caddy can support h2/h2c without h1.

This new mechanism also means graceful shutdown for h2 is easier and we no longer need to track the number of h2 connections. It does require another hack to prevent unintentional h2c request handling, but that hack is minimal.

H2c via protocol upgrade is no longer supported. As far as I know, only curl with use this upgrade if --http2-prior-knowledge is not specified.

@francislavoie
Copy link
Member

Can you link the relevant Go PRs/commits? Curious to see how that evolved.

// enabling h2c because some listener wrapper will wrap the connection that is no longer *tls.Conn
// However, we need to handle the case that if the connection is h2c but h2c is not enabled. We identify
// this type of connection by checking if it's behind a TLS listener wrapper or if it implements tls.ConnectionState.
srv.server.Protocols.SetUnencryptedHTTP2(true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this only be set if h2c, but not h2?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is deliberate. if the handshake succeeds with h2, it will be handled accordingly. h2c is enabled to handle listener wrappers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if the user only configured h2 and not h2c, it'll still have SetUnencryptedHTTP2(true), right? That doesn't seem correct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or wait, you mean if there's LWs then it could appear as though the conn is no longer encrypted cause it's already been decrypted? Is that what you mean? Tricky.

@@ -264,18 +263,6 @@ type Server struct {

// ServeHTTP is the entry point for all HTTP requests.
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// If there are listener wrappers that process tls connections but don't return a *tls.Conn, this field will be nil.
// TODO: Can be removed if https://github.com/golang/go/pull/56110 is ever merged.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa, 3 years later, it's finally in! 👏 Is it too early to drop this though, isn't it only in Go 1.25?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why I leave this as a draft. I have yet to test this thoroughly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this should be left in for now. Other parts seem fine though.

@francislavoie
Copy link
Member

Is there anything in reverseproxy that can be simplified with the new h2c stuff? Or did they only improve the server side but not client side?

@WeidiDeng
Copy link
Member Author

I want to wait until 6955 is merged to work on the reverse proxy protocol stuff.

@mholt
Copy link
Member

mholt commented May 6, 2025

This is still in draft state; would you like another review?

@WeidiDeng WeidiDeng force-pushed the server-h2-handling-using-protocols branch from 42fb301 to c28bab9 Compare May 23, 2025 02:18
@WeidiDeng WeidiDeng closed this May 23, 2025
@WeidiDeng WeidiDeng force-pushed the server-h2-handling-using-protocols branch from 4158f9e to a76d005 Compare May 23, 2025 03:23
@WeidiDeng WeidiDeng reopened this May 23, 2025
@WeidiDeng WeidiDeng marked this pull request as ready for review August 13, 2025 01:03
Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this so long ago 😅 Let's give this a try, it will go out with the next release, so if there are issues I'm sure we will hear about it, and you can help us with them 👍 Thanks again!

@mholt mholt enabled auto-merge (squash) August 22, 2025 14:26
@mholt mholt merged commit 14a63a2 into master Aug 22, 2025
26 checks passed
@mholt mholt deleted the server-h2-handling-using-protocols branch August 22, 2025 14:30
@francislavoie francislavoie added this to the v2.10.1 milestone Aug 22, 2025
mohammed90 pushed a commit to cedricziel/caddy that referenced this pull request Aug 29, 2025
…ts (caddyserver#6961)

* use the new http.Protocols to handle h1, h2 and h2c requests

* fix lint

* keep ConnCtxKey for now

* fix handling for h2c

* check http version while reading the connection

* check if connection implements connectionStater when it should

* add comments about either h1 or h2 must be used in the listener

* fix if check

* return a net.Conn that implements connectionStater if applicable

* remove http/1.1 from alpn if h1 is disabled

* fix matching if only h1 is enabled

---------

Co-authored-by: Matt Holt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants