diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2018-04-12 17:20:18 +0000 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2018-04-12 17:39:03 +0000 |
| commit | 740a209a2ed416fa0be306dca5c84e55954e6924 (patch) | |
| tree | 10f7fab8cf1f52e43928ef65cee764abac41170a /src/net/http/server.go | |
| parent | 7a0bf9436960ffb0b2bd6c7421cd420aa8577402 (diff) | |
| download | go-740a209a2ed416fa0be306dca5c84e55954e6924.tar.xz | |
net/http: don't crash if Server.Server is called with non-comparable Listener
Fixes #24812
Change-Id: If8d496d61b1120233e44c72d854e80cb06bab970
Reviewed-on: https://go-review.googlesource.com/106657
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/net/http/server.go')
| -rw-r--r-- | src/net/http/server.go | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/src/net/http/server.go b/src/net/http/server.go index 114a2263c3..1ae7e2dd43 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -2485,7 +2485,7 @@ type Server struct { nextProtoErr error // result of http2.ConfigureServer if used mu sync.Mutex - listeners map[net.Listener]struct{} + listeners map[*net.Listener]struct{} activeConn map[*conn]struct{} doneChan chan struct{} onShutdown []func() @@ -2621,7 +2621,7 @@ func (s *Server) closeIdleConns() bool { func (s *Server) closeListenersLocked() error { var err error for ln := range s.listeners { - if cerr := ln.Close(); cerr != nil && err == nil { + if cerr := (*ln).Close(); cerr != nil && err == nil { err = cerr } delete(s.listeners, ln) @@ -2765,8 +2765,8 @@ func (srv *Server) Serve(l net.Listener) error { return err } - srv.trackListener(l, true) - defer srv.trackListener(l, false) + srv.trackListener(&l, true) + defer srv.trackListener(&l, false) baseCtx := context.Background() // base is always background, per Issue 16220 ctx := context.WithValue(baseCtx, ServerContextKey, srv) @@ -2843,11 +2843,19 @@ func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error { return srv.Serve(tlsListener) } -func (s *Server) trackListener(ln net.Listener, add bool) { +// trackListener adds or removes a net.Listener to the set of tracked +// listeners. +// +// We store a pointer to interface in the map set, in case the +// net.Listener is not comparable. This is safe because we only call +// trackListener via Serve and can track+defer untrack the same +// pointer to local variable there. We never need to compare a +// Listener from another caller. +func (s *Server) trackListener(ln *net.Listener, add bool) { s.mu.Lock() defer s.mu.Unlock() if s.listeners == nil { - s.listeners = make(map[net.Listener]struct{}) + s.listeners = make(map[*net.Listener]struct{}) } if add { // If the *Server is being reused after a previous |
