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 }