]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: enable automatic HTTP/2 if TLSNextProto is nil
authorBrad Fitzpatrick <bradfitz@golang.org>
Wed, 14 Oct 2015 20:41:36 +0000 (20:41 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 14 Oct 2015 23:21:57 +0000 (23:21 +0000)
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: Andrew Gerrand <adg@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/api/goapi.go
src/go/build/deps_test.go
src/net/http/serve_test.go
src/net/http/server.go

index 01b6defb5ff9ef271849179af753e729dd21caf0..5d1cf05e31b44feac9e6e4a0650059185e61e56e 100644 (file)
@@ -428,10 +428,15 @@ func (w *Walker) Import(name string) (*types.Package, error) {
        }
        w.imported[name] = &importing
 
+       root := w.root
+       if strings.HasPrefix(name, "golang.org/x/") {
+               root = filepath.Join(root, "vendor")
+       }
+
        // 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() {
-               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
index 62bcb12a23f637e8c4939f90ba6a5569b7d66def..e3c146963abbb5c40b262b51700027d05ea2b9ac 100644 (file)
@@ -351,6 +351,7 @@ var pkgDeps = map[string][]string{
                "L4", "NET", "OS",
                "compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
                "net/http/internal",
+               "golang.org/x/net/http2/hpack",
        },
        "net/http/internal": {"L4"},
 
index 11a0a9e1209cc22ed113ffade8ead6c85a3893a4..dddfd401686af497623734afd845de38d6052b3f 100644 (file)
@@ -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 {
        contentLength    int // of request body
        chunked          bool
index ae62e076ddffb9644064795edf6c2966045cd00e..dc4f100e014a26f2cc7bc7da6f38cc806f1f3225 100644 (file)
@@ -1806,7 +1806,8 @@ type Server struct {
        // standard 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.
@@ -1896,6 +1897,7 @@ func (srv *Server) ListenAndServe() error {
 func (srv *Server) Serve(l net.Listener) error {
        defer l.Close()
        var tempDelay time.Duration // how long to sleep on accept failure
+       srv.nextProtoOnce.Do(srv.setNextProtoDefaults)
        for {
                rw, e := l.Accept()
                if e != nil {
@@ -2052,6 +2054,14 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
        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.
 //
 // The new Handler calls h.ServeHTTP to handle each request, but if a