Open neild opened 3 weeks ago
My initial proposal for this in #60746 configured protocols with an ordered []Protocol
. After experimenting with implementation, I think that ordered protocol selection is too complicated. (It's not bad with just two protocols, but what happens if we support HTTP/3, someone asks for HTTP/2->HTTP/3->HTTP/1, and ALPN negotiation picks HTTP/1? Do we drop the connection and retry on HTTP/3?)
I'm not sure about the use of a bitmask to represent sets of protocols. It's simple and we're unlikely to ever run out of 64 bits, but perhaps it's a bit too simple? We could have an opaque type instead:
type Protocol int
// Protocols is a set of protocols.
type Protocols struct {}
func (p *Protocols) Add(Protocol)
func (p *Protocols) Remove(Protocol)
func (p Protocols) Contains(Protocol)
func (p Protocols) All() iter.Seq[Protocol]
This proposal has been added to the active column of the proposals project and will now be reviewed at the weekly proposal review meetings. — rsc for the proposal review group
Does it have to be so general at all? An even more pedestrian API would be:
type Protocols struct { ... } func (p Protocols) HTTP1() bool func (p Protocols) HTTP2() bool func (p Protocols) HTTP3() bool func (p Protocols) SetHTTP1(ok bool) func (p Protocols) SetHTTP2(ok bool) func (p Protocols) SetHTTP3(ok bool)
It's not as cute but it doesn't paint us into any corners and it's very clear.
Thoughts?
Looks good to me.
This issue is part of a project to move
x/net/http2
intostd
: #67810I propose adding a new mechanism for selecting what HTTP versions will be used by a
net/http
Server
orTransport
.Currently, by default
net/http
server listening on a TLS connection will accept both HTTP/1 and HTTP/2 requests;net/http
transport will use HTTP/1 for https requests (never HTTP/2); andnet/http.DefaultTransport
will use HTTP/2 when available and HTTP/1 otherwise for https requests.Users may disable HTTP/2 support by setting
Server.TLSNextProto
orTransport.TLSNextProto
to an empty map.Users may enable HTTP/2 support on a transport by setting
Transport.ForceAttemptHTTP2
.Users may disable HTTP/1 support by importing
golang.org/x/net/http2
using anhttp2.Server
orhttp2.Transport
directly.The net/http package does not currently directly support HTTP/3, but if and when it does, there will need to be a mechanism for enabling or disabling HTTP/3.
The existing APIs for selecting a protocol version are confusing, inconsistent, expose internal implementation details, and don't generalize well to additional protocol versions. The above proposal replaces them with a single, clear mechanism that allows for future expansion.
Example usage: