Преглед изворни кода

http2: make http2.Server access http1's Server via an interface check

The previous way was causing init blocks to be generated which the
linker wasn't smart enough to discard, and the cmd/go tool was once
again including http1 & http2 Servers.

Change-Id: I9d82e14421e0faa96437668f9013d1174f009936
Reviewed-on: https://go-review.googlesource.com/32417
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Daniel Theophanes <kardianos@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Brad Fitzpatrick пре 9 година
родитељ
комит
541150ac4f
2 измењених фајлова са 28 додато и 14 уклоњено
  1. 26 12
      http2/server.go
  2. 2 2
      http2/server_test.go

+ 26 - 12
http2/server.go

@@ -129,10 +129,6 @@ func (s *Server) maxConcurrentStreams() uint32 {
 	return defaultMaxStreams
 }
 
-// List of funcs for ConfigureServer to run. Both h1 and h2 are guaranteed
-// to be non-nil.
-var configServerFuncs []func(h1 *http.Server, h2 *Server) error
-
 // ConfigureServer adds HTTP/2 support to a net/http Server.
 //
 // The configuration conf may be nil.
@@ -213,13 +209,6 @@ func ConfigureServer(s *http.Server, conf *Server) error {
 	return nil
 }
 
-// h1ServerShutdownChan if non-nil provides a func to return a channel
-// that will be closed when the provided *http.Server wants to shut
-// down. This is initialized via an init func in net/http (via its
-// mangled name from x/tools/cmd/bundle). This is only used when http2
-// is bundled into std for now.
-var h1ServerShutdownChan func(*http.Server) <-chan struct{}
-
 // ServeConnOpts are options for the Server.ServeConn method.
 type ServeConnOpts struct {
 	// BaseConfig optionally sets the base configuration
@@ -718,7 +707,7 @@ func (sc *serverConn) serve() {
 	}
 
 	var gracefulShutdownCh <-chan struct{}
-	if sc.hs != nil && h1ServerShutdownChan != nil {
+	if sc.hs != nil {
 		gracefulShutdownCh = h1ServerShutdownChan(sc.hs)
 	}
 
@@ -2646,3 +2635,28 @@ var badTrailer = map[string]bool{
 	"Transfer-Encoding":   true,
 	"Www-Authenticate":    true,
 }
+
+// h1ServerShutdownChan returns a channel that will be closed when the
+// provided *http.Server wants to shut down.
+//
+// This is a somewhat hacky way to get at http1 innards. It works
+// when the http2 code is bundled into the net/http package in the
+// standard library. The alternatives ended up making the cmd/go tool
+// depend on http Servers. This is the lightest option for now.
+// This is tested via the TestServeShutdown* tests in net/http.
+func h1ServerShutdownChan(hs *http.Server) <-chan struct{} {
+	if fn := testh1ServerShutdownChan; fn != nil {
+		return fn(hs)
+	}
+	var x interface{} = hs
+	type I interface {
+		getDoneChan() <-chan struct{}
+	}
+	if hs, ok := x.(I); ok {
+		return hs.getDoneChan()
+	}
+	return nil
+}
+
+// optional test hook for h1ServerShutdownChan.
+var testh1ServerShutdownChan func(hs *http.Server) <-chan struct{}

+ 2 - 2
http2/server_test.go

@@ -3533,8 +3533,8 @@ func TestRequestBodyReadCloseRace(t *testing.T) {
 
 func TestServerGracefulShutdown(t *testing.T) {
 	shutdownCh := make(chan struct{})
-	defer func() { h1ServerShutdownChan = nil }()
-	h1ServerShutdownChan = func(*http.Server) <-chan struct{} { return shutdownCh }
+	defer func() { testh1ServerShutdownChan = nil }()
+	testh1ServerShutdownChan = func(*http.Server) <-chan struct{} { return shutdownCh }
 
 	var st *serverTester
 	handlerDone := make(chan struct{})