1
0
mirror of https://github.com/golang/go synced 2024-11-23 11:50:09 -07:00

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>
This commit is contained in:
Brad Fitzpatrick 2018-04-12 17:20:18 +00:00
parent 7a0bf94369
commit 740a209a2e
2 changed files with 27 additions and 6 deletions

View File

@ -5843,6 +5843,19 @@ func TestServerValidatesMethod(t *testing.T) {
}
}
// Listener for TestServerListenNotComparableListener.
type eofListenerNotComparable []int
func (eofListenerNotComparable) Accept() (net.Conn, error) { return nil, io.EOF }
func (eofListenerNotComparable) Addr() net.Addr { return nil }
func (eofListenerNotComparable) Close() error { return nil }
// Issue 24812: don't crash on non-comparable Listener
func TestServerListenNotComparableListener(t *testing.T) {
var s Server
s.Serve(make(eofListenerNotComparable, 1)) // used to panic
}
func BenchmarkResponseStatusLine(b *testing.B) {
b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {

View File

@ -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