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