Skip to content

net/http: HTTP version selection API #67814

Description

@neild

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions