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

net/http: support HTTP/3 #32204

Open
johanbrandhorst opened this issue May 23, 2019 · 52 comments
Open

net/http: support HTTP/3 #32204

johanbrandhorst opened this issue May 23, 2019 · 52 comments
Labels
FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@johanbrandhorst
Copy link
Member

I searched for an issue to track progress of implementing HTTP/3 in the standard library but couldn't find one, so I'm opening this new issue to track this (presumably inevitable) effort.

HTTP/3 is still an IETF draft, so there's not too much point starting work on this yet. The relevant spec is (currently) available here: https://quicwg.org/base-drafts/draft-ietf-quic-http.html.

Some questions we may want to answer before any work starts:

  1. Should work on this start in one of the x repos, like HTTP/2 did?
  2. What if any existing libraries can be used as a base for the new HTTP/3 work?

Of note is an existing attempt at implementing QUIC and HTTP/3 in pure go: https://github.com/lucas-clemente/quic-go.

@bradfitz bradfitz added this to the Unplanned milestone May 23, 2019
@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 28, 2019
@dsymonds
Copy link
Contributor

Cloudflare now supports HTTP/3, and Chrome and Firefox will shortly start supporting it: https://blog.cloudflare.com/http3-the-past-present-and-future/

@rajveermalviya
Copy link

rajveermalviya commented Dec 14, 2019

Not to say we're in a race, but node has started implementing quic protocol in a draft PR.

Reference

Now, some bad opinions (if the go team is accepting them):

  • net package - dedicated raw quic protocol API, just as tcp/udp?
  • net/http package - http/3 server to be enabled explicitly from an environment variable but http/2 & lower supported implicitly using port reuse between udp (quic;http3) & tcp (http2/http1.1) sockets?

@trivikr
Copy link

trivikr commented Dec 14, 2019

but node has started implementing quic protocol in a draft PR.

Correction: The Node.js QUIC implementation began back in Q1 2019, the draft PR is the result of all that work nodejs/node#23064

@vyrwu
Copy link

vyrwu commented Apr 15, 2020

Is there any progress on this? There are some existing open-source libs like quic-go that can be used for experimenting with quic, but it would be really neat to have something experimental from the std go lib.

@hekmon
Copy link

hekmon commented Oct 9, 2020

🚀
https://blog.chromium.org/2020/10/chrome-is-deploying-http3-and-ietf-quic.html

@hherman1
Copy link

Has there been any word from leadership on whether or not this will be supported?

@ianlancetaylor
Copy link
Contributor

I'm not sure which leadership you are asking about.

I think it's clear that Go must support HTTP/3. This issue is a good place to record the work that needs to be done. But it is one thing to say "we must do this" and it is a very different thing to say "this is how it will be done."

@hherman1
Copy link

Sorry I’m not sure how that came off, I was just wondering if there was any official word on if this will be supported. Couldn’t find any on the issue tracker. Thanks for the quick answer though!

@sylr
Copy link

sylr commented Oct 22, 2020

It seems to me that it is still a long way from now to we must do this.

I might have missed it but so far I did not see any interest shown in this subject from any of the net & net/http usual committers. Also a research about HTTP/3 or QUIC in golang-dev does not seem to yield any significant results.

It would be nice to see a discussion started amongst people actually capable of bringing it into the standard library.

@makew0rld
Copy link

makew0rld commented Oct 24, 2020

Golang might be behind the times for this feature.

It's worth noting that HTTP/3 is not finalized by the IETF at this point. It is not enabled by default in Firefox and has experimental support. Google likes to push this protocol forward a lot and is using it already in Chrome, but it is still experimental and not finalized. I understand the Go team hesitating to start supporting a protocol that isn't even complete yet.

@mholt
Copy link

mholt commented Oct 24, 2020

Hmm, well, Go's standard library has never been one to quickly adopt new technologies -- not without a lot of scrutiny. HTTP/2 might possibly be the exception, but even it was not vendored in from an external package until well after the spec was standardized. HTTP/3 isn't finished being standardized yet.

HTTP/3 is more complex than HTTP/2, and there's a lot of code necessary to make it work. I've been using and deploying lucas-clemente/quic-go for a couple years now (in Caddy, so we're already seeing a lot of experimental production deployments) -- frankly it's a beast. What's the benefit of having it in the standard library right now?

It's OK if it's not in the standard library right away. I'd rather the standard implementation be correct, elegant, and stable, true to the reputation of the Go standard library.

@ShivanshVij
Copy link

ShivanshVij commented Oct 24, 2020

I understand what you’re saying, but the issue is that the NodeJS team had been experimenting with Quic support for months before this release.

Now that companies like Cloudflare and Google are beginning support, it’s unlikely that the IETF standard will change drastically.

There’s no reason not to begin implementation or at least experimentation and make whatever small tweaks are necessary for the general availability release once the standard is completed by IETF.

@ShivanshVij
Copy link

ShivanshVij commented Oct 24, 2020

@mholt is completely correct in saying that whatever finalized HTTP/3 library is released should be elegant and stable. However, what I am saying is that I believe that we should at least begin an in-depth discussion on the topic instead of just saying we will wait for the standard to be completed by IETF.

If we leave it until later, then I can see an issue where people will want to use the vast benefits of HTTP/3 but be unable to do so with Golang. (This is the main reason I have to write my server code in NodeJS right now, HTTP/3 is a requirement for us)

@makew0rld
Copy link

Google has been using and pushing HTTP/3 since before it was even called that, they deployed their super-experimental non-standardized original version of the protocol in Chrome as early as 2012. It is not surprising they are still using and pushing it now, while it is still not standardized. I would argue Cloudflare is also supporting it prematurely, likely to test their implementation at scale.

No browser currently supports HTTP/3 by default. See https://caniuse.com/http3

image

However, what I am saying is that I believe that we should at least begin an in-depth discussion on the topic instead of just saying we will wait for the standard to be completed by IETF.

I agree that beginning discussion would be helpful. I'm just saying I understand why it hasn't happened yet, and I think there is still plenty of time. The current usage and demand for HTTP/3 seems to be effectively zero.

This is the main reason I have to write my server code in NodeJS right now, HTTP/3 is a requirement for us

Why not use quic-go?

@pofl
Copy link

pofl commented Oct 25, 2020

As I see it, QUIC and HTTP/3 are so far into the IETF process that they are hardly bound to change anymore, definitely not substantially. Let me argue that if somebody would start implementing now they will not have to throw away any part of the implementation due to changes to the standard. By lying in wait for the finalization Go is only perpetuating the chicken-and-egg problem.

Not that any of this is a problem. Just my two cents.

@FireMasterK
Copy link

Has there been any progress on bringing an official implementation? Is there any issue that is blocking this?

I can't seem to understand what's blocking this, there seems to be a lot of interest too. Sure, quic-go does the job, but I'm sure it's nice to have official support for quic.

@awnumar
Copy link
Contributor

awnumar commented Apr 2, 2021

Overview of HTTP/3 support amongst clients and servers: https://daniel.haxx.se/blog/2021/04/02/where-is-http-3-right-now/

tldr: the level of HTTP/3 support in servers are surprisingly high considering very few clients enable it by default yet.

I assume that the rest of the browsers will also enable HTTP/3 by default soon, and the specs will be released not too long into the future. That will make HTTP/3 traffic on the web increase significantly.

The TLS library situation will continue to hamper wider adoption among non-browsers and smaller players.

@awnumar
Copy link
Contributor

awnumar commented Apr 12, 2021

A few more browsers support it now: https://caniuse.com/http3

image

@nirui
Copy link

nirui commented Apr 13, 2021

Guys, guys, something to read about:

@schoenenberg
Copy link

QUIC has been published by the IETF as RFC 9000!

See this post: QUIC is now RFC 9000

HN Discussion: https://news.ycombinator.com/item?id=27310349

@DeedleFake
Copy link

Note that that does not include HTTP/3. That'll be a separate RFC later on. I do think that this shows that it's about time to get an official QUIC implementation, though, either directly in net or in something like net/quic. If it starts in golang.org/x/net/quic first, that's fine, too.

@seankhliao
Copy link
Member

seankhliao commented May 28, 2021

Quic is #44886

@DeedleFake
Copy link

Judging by the number of references to this issue above, it seems there are quite a few projects waiting on this for various things. I'm personally just as interested in raw QUIC support as I am HTTP/3. Any chance of it happening? It's been pretty quiet for a while despite both protocols getting standardized.

@DeedleFake
Copy link

Should this issue have a proposal label? There was a proposal that was closed as a duplicate of this issue, but this one isn't labeled as one and I worry that the proposal review team may be overlooking it because of that.

@ianlancetaylor
Copy link
Contributor

I don't think it would be helpful to send this issue through the proposal committee at this point. The proposal committee is useful for coming to agreement on new API or precisely defined new functionality. But so far nobody has described an API or exactly what it means to support HTTP/3 (I don't know myself).

In particular the proposal committee can't cause anybody to actually work on this. That seems like the most useful next step here.

@mholt
Copy link

mholt commented Nov 17, 2022

@marten-seemann Want to work together on a proposal for HTTP/3 in the Go standard library?

@jefer94
Copy link

jefer94 commented Nov 27, 2022

@ianlancetaylor I supposed with "support HTTP/3" they refer to start to implement this draft https://datatracker.ietf.org/doc/html/rfc9114 inside the net package of Go, exists one team have a implementation of QUIC https://github.com/lucas-clemente/quic-go this can be the start point to do the first implementation of HTTP/3, also part of this draft was wrote by the team of QUIC, this team is belong to Google, using set theory you can determine the difference between both protocols and do the parts is not in the intersection, that should be useful to continue with the rest of steps

@jefer94
Copy link

jefer94 commented Nov 27, 2022

Here appear a implementation in other programming languages https://en.wikipedia.org/wiki/HTTP/3 they says have HTTP/3 implemented, if it is true you can copy/paste that code and convert it to Go

@mholt
Copy link

mholt commented Nov 27, 2022

Marten and I have already exchanged some emails on the topic. Go's standard lib would have to implement the QUIC protocol which, unfortunately, has a lot of knobs and callbacks that are needed for secure and efficient deployments. My current understanding is that adding QUIC to the standard library would export considerable API surface area, including on the crypto/tls package, which is probably not desirable. (Maybe some of it could be refactored into an internal package, but still -- not trivial.) To minimize the exported API we'd need to have smart or sane defaults, but it's not clear to me, at least, what those defaults should be in the general case.

The most minimal QUIC implementation would lose a number of security and performance enhancements. Some examples include address verification (which should be done when the server is "under load" -- but only certain kinds of load -- to prevent amplification attacks) advertising HTTP/3 in the Alt-Svc header (which requires knowing the external port number), 0-RTT, WebTransport API, among others.

I suppose a good, minimal starting point for the API would be to have a function like http.ListenAndServeTLS() start a listener on a UDP socket as well as it does for a TCP socket.

For methods like http.Server.Serve(ln, handler), things are a little trickier since you'd have to have a net.Listener as well as a net.PacketConn for the UDP socket. Maybe the standard library could assume the same port as the given listener (if a TCP listener) and start its own UDP listener? But that does feel a bit "magical" for the standard library. (If it was an external library, I'd be more OK with that. But I don't feel right doing that in the standard lib.)

Anyway, many questions remain to be answered in the proposal drafting process.

@james-lawrence
Copy link
Contributor

james-lawrence commented Nov 27, 2022

@mholt I think the questions you should be asking is what kind of surface API would the stdlib need to expose to support QUIC implementations in a composable manner with other transports. there is already a quic implemention for golang in the wild; but it didn't really try to be very composable with other transport APIs in the stdlib. but it has brought improvements to the TLS api just by existing.

focusing on http in particular isn't a great approach as there are far more uses for quic than http. I think the main thing stdlib is missing is a concept of a multiplex transport that has both packet and reliable transport behaviors.

Ideally we wouldn't need to expand on HTTP's api at all if we get the lower level transport API done correctly. we'd just be able to pass the quic.Listener to the http server just like we do now for tcp and unix listeners.

the port question seems misguided; just call http.Serve twice http.Serve(quic, handler) http.Serve(tcp, handler) or write a composite transport listener. if the programmer is using the ":#" method on http then the reasonable assumptions (assume same port) are perfectly fine as they are opting into them.

@komuw
Copy link
Contributor

komuw commented Feb 16, 2023

Related: #58547 : proposal: x/net/quic: add QUIC implementation

@codewinch
Copy link

According to https://caniuse.com/http3 and if I'm reading the chart right, over 70% of clients globally now support HTTP/3, with the main holdouts being Apple Safari. As far as I know, Go doesn't even have an official server in any kind of testing; it's especially strange given that Google was a very strong driver behind the global HTTP/3 adoption.

@kgersen
Copy link

kgersen commented Feb 21, 2023

As a user I'm a bit concerned about how the Go team is handling QUIC and HTTP/3.

It now seems they had no plan up to a few days ago with that x/net/quic proposal (which is just the definition of an API not an actual implementation).

May be we misunderstood but, like a lot of people, we thought quic-go was some kind of official "Google sponsored" effort to add QUIC & HTTP/3 to Go since Lucas Clemente is a Googler... it seems we were wrong as there are clearly no sign of collaboration between them. That one is on us, we should have ask.

But that is concerning in term of timing for an official support of HTTP/3 in Go. We're a couple years late here...and does this implies that quic-go is wasted effort or not worth reusing?

A big reason people are choosing Go is the famous 'batteries included' feature particularly net/http. If Go starts lagging in that area ,less & less people will use it for new projects. Not treating the evolutions of net/http at a higher priority seems, to me, a mistake.

That been said if the Go team ever add HTTP/3 to std lib, it would be nice to avoid some of the "ugly tricks" they used when they added HTTP/2, mainly the 'h2_bundle.go' trick and that awful hardcoded exception in crypto/tls among others...

@codewinch
Copy link

codewinch commented Feb 21, 2023

To be fair, it's not just Go. To a large extent, it's also a reliance on a proper TLS library, since OpenSSL has basically destroyed itself.

For example, this HA Proxy thread has a great explanation of the issues surrounding TLS libs that have QUIC support:

haproxy/haproxy#680

Akamai and NGINX are in the same difficult position of trying to work with a recalcitrant and insecure OpenSSL that doesn't want to move forward, and Linux distributions need to really step up quickly as well.

Perhaps the best option for the Go community as well as everyone else is to move forward with the Rust library WolfSSL, which seems to be a lot safer than OpenSSL (and more stable than Google's own BoringSSL.)

It might seem to be anathema to suggest using a Rust library like WolfSSL in Go, but if it's the best solution then it would let us move forward to H3 fastest, and if all of the other web and server vendors standardize on it, then it'd help get a valid, reliable, fast, and most of all secure solution into the distros that much faster.

@karelbilek
Copy link

karelbilek commented Feb 21, 2023

@codewinch isn't go's using BoringCrypto anyway for the crypto primitives, and native Go code for the rest of the SSL logic?

I don't understand how is OpenSSL relevant here at all

edit: ah the boringcrypto is behind GOEXPERIMENT=boringcrypto. I did not know that. so Go doesn't use any C crypto library by default

@DeedleFake
Copy link

It might seem to be anathema to suggest using a Rust library like WolfSSL in Go

I don't mind that it's Rust (In fact, I think Rust support in cgo would be neat.), but using it would break anything using SSL with CGO_ENABLED=0. If at all possible, the standard library should implement the necessary pieces itself as part of the existing pure Go SSL package that's aready in there.

@ShivanshVij
Copy link

Personally I’d love to use wasm for this - compiling rust to wasm is usually pretty painless, and the wazero project allows you to run wasm code without CGO.

Plus, we’ve already seen demos where go farms out to a rust wasm binary to do regex (https://github.com/loopholelabs/scale-benchmarks) and the perf using wazero is pretty good. (@codefromthecrypt)

With all that being said however, I don’t think the biggest issue is what kind of SSL lib we should use (or how) - it’s trying to find the fastest way to add HTTP/3 support (ie. with the least amount of work).

Being able to use rust via CGO is definitely cool (and I’d love to see it too!) but the go team would have to first add that feature, then integrate a foreign SSL library, and then (and only then) could they start work on the HTTP/3 implementation.

Frankly the easiest path forward would be to take the existing quic-go implementation and just integrate it into the stdlib.

Obviously you’d need to rewrite parts of it but if it already works, why throw it away?

@DeedleFake
Copy link

DeedleFake commented Feb 21, 2023

the wazero project allows you to run wasm code without CGO

The issue isn't running it but rather compilation. This change would require a Rust compiler on the system in order to build the Go standard library, and especially with the new changes in 1.20 to not ship a pre-compiled standard library with distributions of Go, this seems like a rather huge change and potential major problem for many, many people downstream.

Frankly the easiest path forward would be to take the existing quic-go implementation and just integrate it into the stdlib.

I agree, that seems like the best option to me, too. I'd like some API cleanups and whatnot, plus better integration with, say, net.Dial() possible, but the implementation itself clearly seems to work pretty well.

@wtarreau
Copy link

using a Rust library like WolfSSL

WolfSSL is C, not Rust. And it builds pretty fast (5 seconds or so). The main issue with WolfSSL is that it's not particularly dynamic, it was initially designed for embedded systems so it has a hundred or so of configure options and almost needs to be configured for the target use case. However its coverage of the openssl API seems to be pretty large (we do have regtests failing due to missing mappings but a lot of stuff seems there already). I think this lib just needs more users to start to figure what a generic use case could be and at least support being pre-built for such use cases and shipped as-is by distros.

@ahmadkakarr

This comment was marked as spam.

@32bitx64bit
Copy link

32bitx64bit commented Oct 18, 2023

Any news on this? All major browsers but safari ofc support it.
I do believe this should be considered. As having standards is a must have in everything.

just a side note safari technically supports it in its development branch or known as "technology preview"

@DeedleFake
Copy link

@32bitx64bit

It's being worked on, but a QUIC implementation needs to be created first. That's also being worked on: https://pkg.go.dev/golang.org/x/net/internal/quic

@valdemarpavesi

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests