Skip to content
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

reverseproxy: Support HTTP/3 transport to backend #6312

Merged
merged 1 commit into from
May 20, 2024
Merged

reverseproxy: Support HTTP/3 transport to backend #6312

merged 1 commit into from
May 20, 2024

Conversation

mholt
Copy link
Member

@mholt mholt commented May 10, 2024

VERY EXPERIMENTAL. Enables HTTP/3 protocol from proxy to backend ("upstream").

I still don't fully understand why this would be needed/useful, but here is a quick stab attempt with the APIs available to us.

Enabling HTTP/3 necessarily disables other HTTP versions. (If you specify version "3" in your config, you cannot have any other versions.) We do not support protocol downgrade or negotiation like web browsers do. That would probably add considerable latency and complexity where you should already have control over the backends. Additionally, other HTTP transport options don't apply to the HTTP/3 round-tripper because it does not use the http.Transport type like the lower HTTP versions.

Example Caddyfile:

# for demonstration purposes, the backend will ONLY support HTTP/3,
# but of course it doesn't have to be this way
{
	servers :1235 {
		protocols h3
	}
}

# this runs the proxy on HTTP but you can use HTTPS in yours
:1234 {
	reverse_proxy localhost:1235 {
		transport http {
			tls
			versions 3
		}
	}
	log
}

# this is the HTTP/3 backend
localhost:1235 {
	log
	respond "Hello world!"
}

Then run curl -v "http://localhost:1234/" and you'll see the response on the front-end using HTTP/1.1, but the proxy used HTTP/3 to the backend.

In the backend (:1235) we log the request so you can verify that it shows "proto": "HTTP/3.0" for the proxied request. The frontend (:1234) will log "proto": "HTTP/1.1".

Anyway, this seems to work, but with the limitations I mentioned above. We have similar, albeit slightly less tight, restrictions on the "h2c" transport as well.

(@marten-seemann You might like to know we're trying this.)

Closes #5086

@mholt mholt added the feature ⚙️ New feature or request label May 10, 2024
@marten-seemann
Copy link
Contributor

Interesting! As far as I know, this is pretty uncommon, most CDNs don't use H3 for connecting to the backend.

The fact that this is H3-only shows that there'd be value in creating an HTTP client that properly does Happy Eyeballs v3 (Tracking issue: quic-go/quic-go#4336. Not sure though if this would necessarily live inside of quic-go, or maybe in a small repo on the side).

@francislavoie
Copy link
Member

This also means tls must be enabled, right? I don't think it's valid to do HTTP over QUIC? I can't see how this would ever have a performance advantage over HTTP/1.1 in private networks if it had to add TLS overhead 🤔

Anyway I see no reason not to merge this as-is. If it seems to work, that's cool. Fun toy, I guess.

@mholt
Copy link
Member Author

mholt commented May 11, 2024

Yeah, if you take out tls it won't work.

@mholt
Copy link
Member Author

mholt commented May 20, 2024

Eh, this is a pretty low-friction change and shouldn't affect any existing configs since it requires an explicit version 3 be configured; so I might just merge this for the pre-release and we can see how it goes.

@mholt mholt merged commit 5f6758d into master May 20, 2024
23 checks passed
@mholt mholt deleted the proxy-h3 branch May 20, 2024 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature ⚙️ New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

http/3 support in reverse_proxy module
3 participants