github.com/searKing/golang/go@v1.2.117/net/mux/server.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package mux
     6  
     7  import (
     8  	"context"
     9  	"crypto/tls"
    10  	"io"
    11  	"log"
    12  	"net"
    13  	"sync"
    14  	"time"
    15  
    16  	net_ "github.com/searKing/golang/go/net"
    17  	http_ "github.com/searKing/golang/go/net/http"
    18  	"github.com/searKing/golang/go/strings"
    19  	"github.com/searKing/golang/go/sync/atomic"
    20  )
    21  
    22  // for readability of sniffTimeout
    23  var noTimeout time.Duration
    24  var noTimeoutDeadline time.Time
    25  
    26  // NewServer wraps NewServerWithContext using the background context.
    27  //
    28  //go:generate go-option -type "Server"
    29  func NewServer() *Server {
    30  	return NewServerWithContext(context.Background())
    31  }
    32  
    33  // NewServerWithContext returns a new Server.
    34  func NewServerWithContext(ctx context.Context) *Server {
    35  	return &Server{
    36  		ctx:          ctx,
    37  		maxIdleConns: 1024,
    38  		errHandler:   ignoreErrorHandler,
    39  	}
    40  }
    41  
    42  // Server is a multiplexer for network connections.
    43  type Server struct {
    44  	Handler HandlerConn // handler to invoke, mux.DefaultServeMux if nil
    45  
    46  	// maxIdleConns controls the maximum number of idle (keep-alive)
    47  	// connections across all hosts. Zero means no limit.
    48  	maxIdleConns int
    49  	errHandler   ErrorHandler
    50  
    51  	// ConnStateHook specifies an optional callback function that is
    52  	// called when a client connection changes state. See the
    53  	// ConnStateHook type and associated constants for details.
    54  	ConnStateHook func(net.Conn, ConnState)
    55  	// ErrorLog specifies an optional logger for errors accepting
    56  	// connections, unexpected behavior from handlers, and
    57  	// underlying FileSystem errors.
    58  	// If nil, logging is done via the log package's standard logger.
    59  	errorLog   *log.Logger
    60  	ctx        context.Context
    61  	inShutdown atomic.Bool // accessed atomically (non-zero means we're in Shutdown)
    62  
    63  	mu         sync.Mutex
    64  	listeners  map[*net.Listener]struct{}
    65  	activeConn map[*conn]struct{}
    66  	doneChan   chan struct{}
    67  	onShutdown []func()
    68  }
    69  
    70  func (srv *Server) getDoneChan() <-chan struct{} {
    71  	srv.mu.Lock()
    72  	defer srv.mu.Unlock()
    73  	return srv.getDoneChanLocked()
    74  }
    75  
    76  func (srv *Server) getDoneChanLocked() chan struct{} {
    77  	if srv.doneChan == nil {
    78  		srv.doneChan = make(chan struct{})
    79  	}
    80  	return srv.doneChan
    81  }
    82  
    83  func (srv *Server) closeDoneChanLocked() {
    84  	ch := srv.getDoneChanLocked()
    85  	select {
    86  	case <-ch:
    87  		// Already closed. Don't close again.
    88  	default:
    89  		// Safe to close here. We're the only closer, guarded
    90  		// by s.mu.
    91  		close(ch)
    92  	}
    93  }
    94  
    95  // Context returns the request's context. To change the context, use
    96  // WithContext.
    97  //
    98  // The returned context is always non-nil; it defaults to the
    99  // background context.
   100  func (srv *Server) Context() context.Context {
   101  	if srv.ctx != nil {
   102  		return srv.ctx
   103  	}
   104  	return context.Background()
   105  }
   106  
   107  func (srv *Server) logf(format string, args ...any) {
   108  	if srv.errorLog != nil {
   109  		srv.errorLog.Printf(format, args...)
   110  	} else {
   111  		log.Printf(format, args...)
   112  	}
   113  }
   114  
   115  // Create new connection from rwc.
   116  func (srv *Server) newConn(rwc net.Conn) *conn {
   117  	return &conn{
   118  		server: srv,
   119  		muc:    newMuxConn(rwc),
   120  	}
   121  }
   122  
   123  // Serve starts multiplexing the listener. Serve blocks and perhaps
   124  // should be invoked concurrently within a go routine.
   125  // Serve accepts incoming connections on the ServeMux l, creating a
   126  // new service goroutine for each. The service goroutines read requests and
   127  // then call srv.HandlerConn to reply to them.
   128  func (srv *Server) Serve(l net.Listener) error {
   129  	l = net_.OnceCloseListener(l)
   130  	defer l.Close()
   131  
   132  	if srv.shuttingDown() {
   133  		return ErrServerClosed
   134  	}
   135  
   136  	if !srv.trackListener(&l, true) {
   137  		return ErrServerClosed
   138  	}
   139  	defer srv.trackListener(&l, false)
   140  
   141  	var tempDelay time.Duration // how long to sleep on accept failure
   142  	ctx := context.WithValue(srv.Context(), ServerContextKey, srv)
   143  
   144  	for {
   145  		rw, err := l.Accept()
   146  		if err != nil {
   147  			select {
   148  			case <-ctx.Done():
   149  				return ErrServerClosed
   150  			case <-srv.getDoneChan():
   151  				return ErrServerClosed
   152  			default:
   153  			}
   154  			if !srv.handleErr(err) {
   155  				return err
   156  			}
   157  
   158  			if ne, ok := err.(net.Error); ok && ne.Temporary() {
   159  				if tempDelay == 0 {
   160  					tempDelay = 5 * time.Millisecond
   161  				} else {
   162  					tempDelay *= 2
   163  				}
   164  				if max := 1 * time.Second; tempDelay > max {
   165  					tempDelay = max
   166  				}
   167  				srv.logf("cmux: Accept error: %v; retrying in %v", err, tempDelay)
   168  				time.Sleep(tempDelay)
   169  				continue
   170  			}
   171  			return err
   172  		}
   173  		tempDelay = 0
   174  
   175  		c := srv.newConn(rw)
   176  		c.setState(c.muc, ConnStateNew) // before Serve can return
   177  
   178  		go c.serve(ctx)
   179  
   180  	}
   181  }
   182  
   183  // ServeTLS accepts incoming connections on the ServeMux l, creating a
   184  // new service goroutine for each. The service goroutines perform TLS
   185  // setup and then read requests, calling srv.HandlerConn to reply to them.
   186  //
   187  // Files containing a certificate and matching private key for the
   188  // server must be provided if neither the ServeMux's
   189  // TLSConfig.Certificates nor TLSConfig.GetCertificate are populated.
   190  // If the certificate is signed by a certificate authority, the
   191  // certFile should be the concatenation of the server's certificate,
   192  // any intermediates, and the CA's certificate.
   193  //
   194  // ServeTLS always returns a non-nil error. After Shutdown or Close, the
   195  // returned error is ErrServerClosed.
   196  func (srv *Server) ServeTLS(l net.Listener, tLSConfig *tls.Config, certFile, keyFile string) error {
   197  	config := http_.CloneTLSConfig(tLSConfig)
   198  	if !strings.SliceContains(config.NextProtos, "http/1.1") {
   199  		config.NextProtos = append(config.NextProtos, "http/1.1")
   200  	}
   201  
   202  	configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
   203  	if !configHasCert || certFile != "" || keyFile != "" {
   204  		var err error
   205  		config.Certificates = make([]tls.Certificate, 1)
   206  		config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
   207  		if err != nil {
   208  			return err
   209  		}
   210  	}
   211  
   212  	tlsListener := tls.NewListener(l, config)
   213  	return srv.Serve(tlsListener)
   214  }
   215  
   216  // serverHandler delegates to either the server's HandlerConn or
   217  // DefaultServeMux and also handles "OPTIONS *" requests.
   218  type serverHandler struct {
   219  	srv *Server
   220  }
   221  
   222  func (sh serverHandler) Handler(c *sniffConn) HandlerConn {
   223  	handler := sh.srv.Handler
   224  	if handler == nil {
   225  		handler = DefaultServeMux
   226  	}
   227  	return handler
   228  }
   229  
   230  func (sh serverHandler) handler() HandlerConn {
   231  	handler := sh.srv.Handler
   232  	if handler == nil {
   233  		handler = DefaultServeMux
   234  	}
   235  	return handler
   236  }
   237  func (sh serverHandler) Serve(c net.Conn) {
   238  	sh.handler().Serve(c)
   239  }
   240  
   241  func (sh serverHandler) Close() error {
   242  	if closer, ok := sh.handler().(io.Closer); ok {
   243  		return closer.Close()
   244  	}
   245  	return nil
   246  }
   247  
   248  // ListenAndServe listens on the TCP network address srv.Addr and then
   249  // calls Serve to handle requests on incoming connections.
   250  // Accepted connections are configured to enable TCP keep-alives.
   251  //
   252  // If srv.Addr is blank, ":http" is used.
   253  //
   254  // ListenAndServe always returns a non-nil error. After Shutdown or Close,
   255  // the returned error is ErrServerClosed.
   256  func (srv *Server) ListenAndServe(addr string) error {
   257  	if srv.shuttingDown() {
   258  		return ErrServerClosed
   259  	}
   260  	if addr == "" {
   261  		addr = ":tcp"
   262  	}
   263  
   264  	ln, err := net.Listen("tcp", addr)
   265  	if err != nil {
   266  		return err
   267  	}
   268  	return srv.Serve(ln)
   269  }
   270  
   271  // ListenAndServeTLS listens on the TCP network address srv.Addr and
   272  // then calls ServeTLS to handle requests on incoming TLS connections.
   273  // Accepted connections are configured to enable TCP keep-alives.
   274  //
   275  // Filenames containing a certificate and matching private key for the
   276  // server must be provided if neither the ServeMux's TLSConfig.Certificates
   277  // nor TLSConfig.GetCertificate are populated. If the certificate is
   278  // signed by a certificate authority, the certFile should be the
   279  // concatenation of the server's certificate, any intermediates, and
   280  // the CA's certificate.
   281  //
   282  // If srv.Addr is blank, ":https" is used.
   283  //
   284  // ListenAndServeTLS always returns a non-nil error. After Shutdown or
   285  // Close, the returned error is ErrServerClosed.
   286  func (srv *Server) ListenAndServeTLS(addr string, tlsConfig *tls.Config, certFile, keyFile string) error {
   287  	if srv.shuttingDown() {
   288  		return ErrServerClosed
   289  	}
   290  	if addr == "" {
   291  		addr = ":https"
   292  	}
   293  
   294  	ln, err := net.Listen("tcp", addr)
   295  	if err != nil {
   296  		return err
   297  	}
   298  
   299  	defer ln.Close()
   300  
   301  	return srv.ServeTLS(net_.TcpKeepAliveListener(ln.(*net.TCPListener), 3*time.Minute), tlsConfig, certFile, keyFile)
   302  }
   303  
   304  // ListenAndServe listens on the TCP network address addr and then calls
   305  // Serve with handler to handle requests on incoming connections.
   306  // Accepted connections are configured to enable TCP keep-alives.
   307  //
   308  // The handler is typically nil, in which case the DefaultServeMux is used.
   309  //
   310  // ListenAndServe always returns a non-nil error.
   311  func ListenAndServe(addr string, handler HandlerConn) error {
   312  	server := NewServer()
   313  	server.Handler = handler
   314  	return server.ListenAndServe(addr)
   315  }
   316  
   317  // ListenAndServeTLS acts identically to ListenAndServe, except that it
   318  // expects HTTPS connections. Additionally, files containing a certificate and
   319  // matching private key for the server must be provided. If the certificate
   320  // is signed by a certificate authority, the certFile should be the concatenation
   321  // of the server's certificate, any intermediates, and the CA's certificate.
   322  func ListenAndServeTLS(addr string, handler HandlerConn, tlsConfig *tls.Config, certFile, keyFile string) error {
   323  	server := NewServer()
   324  	server.Handler = handler
   325  	return server.ListenAndServeTLS(addr, tlsConfig, certFile, keyFile)
   326  }
   327  
   328  // Close immediately closes all active net.Listeners and any
   329  // connections in state StateNew, StateActive, or StateIdle. For a
   330  // graceful shutdown, use Shutdown.
   331  //
   332  // Close does not attempt to close (and does not even know about)
   333  // any hijacked connections, such as WebSockets.
   334  //
   335  // Close returns any error returned from closing the ServeMux's
   336  // underlying ServeMux(s).
   337  func (srv *Server) Close() error {
   338  	srv.inShutdown.Store(true)
   339  	srv.mu.Lock()
   340  	defer srv.mu.Unlock()
   341  	srv.closeDoneChanLocked()
   342  
   343  	err := srv.closeListenersLocked()
   344  	for c := range srv.activeConn {
   345  		c.close()
   346  		delete(srv.activeConn, c)
   347  	}
   348  	if srv.Handler == nil {
   349  		DefaultServeMux.Close()
   350  	} else {
   351  		if closer, ok := srv.Handler.(io.Closer); ok {
   352  			closer.Close()
   353  		}
   354  	}
   355  	return err
   356  }
   357  
   358  // shutdownPollInterval is how often we poll for quiescence
   359  // during ServeMux.Shutdown. This is lower during tests, to
   360  // speed up tests.
   361  // Ideally we could find a solution that doesn't involve polling,
   362  // but which also doesn't have a high runtime cost (and doesn't
   363  // involve any contentious mutexes), but that is left as an
   364  // exercise for the reader.
   365  var shutdownPollInterval = 500 * time.Millisecond
   366  
   367  // Shutdown gracefully shuts down the server without interrupting any
   368  // active connections. Shutdown works by first closing all open
   369  // listeners, then closing all idle connections, and then waiting
   370  // indefinitely for connections to return to idle and then shut down.
   371  // If the provided context expires before the shutdown is complete,
   372  // Shutdown returns the context's error, otherwise it returns any
   373  // error returned from closing the ServeMux's underlying ServeMux(s).
   374  //
   375  // When Shutdown is called, Serve, ListenAndServe, and
   376  // ListenAndServeTLS immediately return ErrServerClosed. Make sure the
   377  // program doesn't exit and waits instead for Shutdown to return.
   378  //
   379  // Shutdown does not attempt to close nor wait for hijacked
   380  // connections such as WebSockets. The caller of Shutdown should
   381  // separately notify such long-lived connections of shutdown and wait
   382  // for them to close, if desired. See RegisterOnShutdown for a way to
   383  // register shutdown notification functions.
   384  //
   385  // Once Shutdown has been called on a server, it may not be reused;
   386  // future calls to methods such as Serve will return ErrServerClosed.
   387  func (srv *Server) Shutdown(ctx context.Context) error {
   388  	srv.inShutdown.Store(true)
   389  	srv.mu.Lock()
   390  	lnerr := srv.closeListenersLocked()
   391  	srv.closeDoneChanLocked()
   392  
   393  	for _, f := range srv.onShutdown {
   394  		go f()
   395  	}
   396  	srv.mu.Unlock()
   397  
   398  	ticker := time.NewTicker(shutdownPollInterval)
   399  	defer ticker.Stop()
   400  	for {
   401  		if srv.closeIdleConns() {
   402  			return lnerr
   403  		}
   404  		select {
   405  		case <-ctx.Done():
   406  			return ctx.Err()
   407  		case <-ticker.C:
   408  		}
   409  	}
   410  }
   411  
   412  // RegisterOnShutdown registers a function to call on Shutdown.
   413  // This can be used to gracefully shutdown connections that have
   414  // undergone NPN/ALPN protocol upgrade or that have been hijacked.
   415  // This function should start protocol-specific graceful shutdown,
   416  // but should not wait for shutdown to complete.
   417  func (srv *Server) RegisterOnShutdown(f func()) {
   418  	srv.mu.Lock()
   419  	srv.onShutdown = append(srv.onShutdown, f)
   420  	srv.mu.Unlock()
   421  }
   422  
   423  // HandleError registers an error handler that handles listener errors.
   424  func (srv *Server) HandleError(h ErrorHandler) {
   425  	srv.errHandler = h
   426  }
   427  
   428  func (srv *Server) handleErr(err error) bool {
   429  	if srv.errHandler == nil {
   430  		return true
   431  	}
   432  	if !srv.errHandler.Continue(err) {
   433  		return false
   434  	}
   435  
   436  	if ne, ok := err.(net.Error); ok {
   437  		return ne.Temporary()
   438  	}
   439  
   440  	return false
   441  }
   442  
   443  // trackListener adds or removes a net.ServeMux to the set of tracked listeners.
   444  //
   445  // We store a pointer to interface in the map set, in case the
   446  // net.ServeMux is not comparable. This is safe because we only call
   447  // trackListener via Serve and can track+defer untrack the same
   448  // pointer to local variable there. We never need to compare a
   449  // ServeMux from another caller.
   450  //
   451  // It reports whether the server is still up (not Shutdown or Closed).
   452  func (srv *Server) trackListener(ln *net.Listener, add bool) bool {
   453  	srv.mu.Lock()
   454  	defer srv.mu.Unlock()
   455  	if add {
   456  		if srv.shuttingDown() {
   457  			return false
   458  		}
   459  		if srv.listeners == nil {
   460  			srv.listeners = make(map[*net.Listener]struct{})
   461  		}
   462  		srv.listeners[ln] = struct{}{}
   463  		return true
   464  	}
   465  	delete(srv.listeners, ln)
   466  	return true
   467  }
   468  
   469  func (srv *Server) trackConn(c *conn, add bool) {
   470  	srv.mu.Lock()
   471  	defer srv.mu.Unlock()
   472  	if add {
   473  		if srv.activeConn == nil {
   474  			srv.activeConn = make(map[*conn]struct{})
   475  		}
   476  		srv.activeConn[c] = struct{}{}
   477  	} else {
   478  		delete(srv.activeConn, c)
   479  	}
   480  }
   481  
   482  func (srv *Server) shuttingDown() bool {
   483  	return srv.inShutdown.Load()
   484  }
   485  
   486  // closeIdleConns closes all idle connections and reports whether the
   487  // server is quiescent.
   488  func (srv *Server) closeIdleConns() bool {
   489  	srv.mu.Lock()
   490  	defer srv.mu.Unlock()
   491  	quiescent := true
   492  	for c := range srv.activeConn {
   493  		st, unixSec := c.getState()
   494  		// Issue 22682: treat StateNew connections as if
   495  		// they're idle if we haven't read the first request's
   496  		// header in over 5 seconds.
   497  		if st == ConnStateNew && unixSec < time.Now().Unix()-5 {
   498  			st = ConnStateIdle
   499  		}
   500  		if st != ConnStateIdle || unixSec == 0 {
   501  			// Assume unixSec == 0 means it's a very new
   502  			// connection, without state set yet.
   503  			quiescent = false
   504  			continue
   505  		}
   506  		c.close()
   507  		delete(srv.activeConn, c)
   508  	}
   509  	return quiescent
   510  }
   511  
   512  func (srv *Server) closeListenersLocked() error {
   513  	var err error
   514  	for ln := range srv.listeners {
   515  		if cerr := (*ln).Close(); cerr != nil && err == nil {
   516  			err = cerr
   517  		}
   518  		delete(srv.listeners, ln)
   519  	}
   520  	return err
   521  }