Description
This issue is part of a project to move x/net/http2
into std
: #67810
I propose adding a new mechanism for selecting what HTTP versions will be used by a net/http
Server
or Transport
.
// A Protocol is a bitmask of HTTP protocols.
type Protocol uint64
// Contains reports whether p contains all protocols in v.
func (p Protocol) Contains(v Protocol) bool { return p&v != 0 }
const (
// HTTP1 is the HTTP/1.0 and HTTP/1.1 protocols.
// HTTP1 is supported on both unsecured TCP and secured TLS connections.
HTTP1 Protocol = (1 << iota)
// HTTP2 is the HTTP/2 protocol over a TLS connection.
HTTP2
)
type Server { // contains unchanged fields
// Protocols is the set of protocols accepted by the server.
// If the set is empty, the default is usually HTTP/1 and HTTP/2.
// The default is HTTP/1 only if TLSNextProto is non-nil
// and does not contain an "h2" entry.
Protocols Protocol
}
type Transport { // contains unchanged fields
// Protocols is the set of protocols supported by the transport.
// If zero, the default is usually HTTP/1 only.
// The default is HTTP/1 and HTTP/2 if ForceAttemptHTTP2 is true,
// or if TLSNextProto contains an "h2" entry.
Protocols Protocol
}
Currently, by default
- a
net/http
server listening on a TLS connection will accept both HTTP/1 and HTTP/2 requests; - a
net/http
transport will use HTTP/1 for https requests (never HTTP/2); and net/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
or Transport.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 an http2.Server
or http2.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:
s := &http.Server{}
s.Protocols = HTTP1 // disable HTTP/2 support
tr := &http.Transport{}
tr.Protocols = HTTP1 | HTTP2 // enable HTTP/2 support