Commit 20736fca authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: enable automatic HTTP/2 if TLSNextProto is nil

This enables HTTP/2 by default (for https only) if the user didn't
configure anything in their NPN/ALPN map. If they're using SPDY or an
alternate http2 or a newer http2 from x/net/http2, we do nothing
and don't use the standard library's vendored copy of x/net/http2.

Upstream remains golang.org/x/net/http2.

Update #6891

Change-Id: I69a8957a021a00ac353f9d7fdb9a40a5b69f2199
Reviewed-on: https://go-review.googlesource.com/15828
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarAndrew Gerrand <adg@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 7a3dcd2d
...@@ -428,10 +428,15 @@ func (w *Walker) Import(name string) (*types.Package, error) { ...@@ -428,10 +428,15 @@ func (w *Walker) Import(name string) (*types.Package, error) {
} }
w.imported[name] = &importing w.imported[name] = &importing
root := w.root
if strings.HasPrefix(name, "golang.org/x/") {
root = filepath.Join(root, "vendor")
}
// Determine package files. // Determine package files.
dir := filepath.Join(w.root, filepath.FromSlash(name)) dir := filepath.Join(root, filepath.FromSlash(name))
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() { if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
log.Fatalf("no source in tree for package %q", pkg) log.Fatalf("no source in tree for import %q: %v", name, err)
} }
context := w.context context := w.context
......
...@@ -351,6 +351,7 @@ var pkgDeps = map[string][]string{ ...@@ -351,6 +351,7 @@ var pkgDeps = map[string][]string{
"L4", "NET", "OS", "L4", "NET", "OS",
"compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug", "compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
"net/http/internal", "net/http/internal",
"golang.org/x/net/http2/hpack",
}, },
"net/http/internal": {"L4"}, "net/http/internal": {"L4"},
......
...@@ -1068,6 +1068,22 @@ func TestTLSServer(t *testing.T) { ...@@ -1068,6 +1068,22 @@ func TestTLSServer(t *testing.T) {
}) })
} }
func TestAutomaticHTTP2(t *testing.T) {
ln, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatal(err)
}
ln.Close() // immediately (not a defer!)
var s Server
if err := s.Serve(ln); err == nil {
t.Fatal("expected an error")
}
on := s.TLSNextProto["h2"] != nil
if !on {
t.Errorf("http2 wasn't automatically enabled")
}
}
type serverExpectTest struct { type serverExpectTest struct {
contentLength int // of request body contentLength int // of request body
chunked bool chunked bool
......
...@@ -1806,7 +1806,8 @@ type Server struct { ...@@ -1806,7 +1806,8 @@ type Server struct {
// standard logger. // standard logger.
ErrorLog *log.Logger ErrorLog *log.Logger
disableKeepAlives int32 // accessed atomically. disableKeepAlives int32 // accessed atomically.
nextProtoOnce sync.Once // guards initialization of TLSNextProto in Serve
} }
// A ConnState represents the state of a client connection to a server. // A ConnState represents the state of a client connection to a server.
...@@ -1896,6 +1897,7 @@ func (srv *Server) ListenAndServe() error { ...@@ -1896,6 +1897,7 @@ func (srv *Server) ListenAndServe() error {
func (srv *Server) Serve(l net.Listener) error { func (srv *Server) Serve(l net.Listener) error {
defer l.Close() defer l.Close()
var tempDelay time.Duration // how long to sleep on accept failure var tempDelay time.Duration // how long to sleep on accept failure
srv.nextProtoOnce.Do(srv.setNextProtoDefaults)
for { for {
rw, e := l.Accept() rw, e := l.Accept()
if e != nil { if e != nil {
...@@ -2052,6 +2054,14 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error { ...@@ -2052,6 +2054,14 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
return srv.Serve(tlsListener) return srv.Serve(tlsListener)
} }
func (srv *Server) setNextProtoDefaults() {
// Enable HTTP/2 by default if the user hasn't otherwise
// configured their TLSNextProto map.
if srv.TLSNextProto == nil {
http2ConfigureServer(srv, nil)
}
}
// TimeoutHandler returns a Handler that runs h with the given time limit. // TimeoutHandler returns a Handler that runs h with the given time limit.
// //
// The new Handler calls h.ServeHTTP to handle each request, but if a // The new Handler calls h.ServeHTTP to handle each request, but if a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment