github.com/iotexproject/iotex-core@v1.14.1-rc1/pkg/util/httputil/httputil.go (about) 1 package httputil 2 3 import ( 4 "net" 5 "net/http" 6 "time" 7 8 "golang.org/x/net/netutil" 9 ) 10 11 const ( 12 _connectionCount = 400 13 ) 14 15 type ( 16 // ServerOption is a server option 17 ServerOption func(*serverConfig) 18 19 serverConfig struct { 20 ReadHeaderTimeout time.Duration 21 ReadTimeout time.Duration 22 WriteTimeout time.Duration 23 IdleTimeout time.Duration 24 } 25 ) 26 27 // DefaultServerConfig is the default server config 28 var DefaultServerConfig = serverConfig{ 29 ReadHeaderTimeout: 5 * time.Second, 30 ReadTimeout: 30 * time.Second, 31 WriteTimeout: 30 * time.Second, 32 IdleTimeout: 120 * time.Second, 33 } 34 35 // ReadHeaderTimeout sets header timeout 36 func ReadHeaderTimeout(h time.Duration) ServerOption { 37 return func(cfg *serverConfig) { 38 cfg.ReadHeaderTimeout = h 39 } 40 } 41 42 // NewServer creates a HTTP server with time out settings. 43 func NewServer(addr string, handler http.Handler, opts ...ServerOption) http.Server { 44 cfg := DefaultServerConfig 45 for _, opt := range opts { 46 opt(&cfg) 47 } 48 49 return http.Server{ 50 ReadHeaderTimeout: cfg.ReadHeaderTimeout, 51 ReadTimeout: cfg.ReadTimeout, 52 WriteTimeout: cfg.WriteTimeout, 53 IdleTimeout: cfg.IdleTimeout, 54 Addr: addr, 55 Handler: handler, 56 } 57 } 58 59 // LimitListener creates a tcp keep-alive listener with 400 maximum connections. 60 func LimitListener(addr string) (net.Listener, error) { 61 if addr == "" { 62 addr = ":http" 63 } 64 ln, err := net.Listen("tcp", addr) 65 if err != nil { 66 return ln, err 67 } 68 return netutil.LimitListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, _connectionCount), nil 69 } 70 71 // tcpKeepAliveListener sets TCP keep-alive timeouts on accepted 72 // connections. It's used by ListenAndServe and ListenAndServeTLS so 73 // dead TCP connections (e.g. closing laptop mid-download) eventually 74 // go away. 75 // refer: https://golang.org/src/net/http/server.go 76 type tcpKeepAliveListener struct { 77 *net.TCPListener 78 } 79 80 func (ln tcpKeepAliveListener) Accept() (net.Conn, error) { 81 tc, err := ln.AcceptTCP() 82 if err != nil { 83 return nil, err 84 } 85 86 if err = tc.SetKeepAlive(true); err != nil { 87 return nil, err 88 } 89 90 if err = tc.SetKeepAlivePeriod(3 * time.Minute); err != nil { 91 return nil, err 92 } 93 94 return tc, nil 95 }