Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

server.go 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. // This code is highly inspired by endless go
  5. package graceful
  6. import (
  7. "crypto/tls"
  8. "io/ioutil"
  9. "net"
  10. "os"
  11. "strings"
  12. "sync"
  13. "syscall"
  14. "time"
  15. "code.gitea.io/gitea/modules/log"
  16. )
  17. var (
  18. // DefaultReadTimeOut default read timeout
  19. DefaultReadTimeOut time.Duration
  20. // DefaultWriteTimeOut default write timeout
  21. DefaultWriteTimeOut time.Duration
  22. // DefaultMaxHeaderBytes default max header bytes
  23. DefaultMaxHeaderBytes int
  24. )
  25. func init() {
  26. DefaultMaxHeaderBytes = 0 // use http.DefaultMaxHeaderBytes - which currently is 1 << 20 (1MB)
  27. }
  28. // ServeFunction represents a listen.Accept loop
  29. type ServeFunction = func(net.Listener) error
  30. // Server represents our graceful server
  31. type Server struct {
  32. network string
  33. address string
  34. listener net.Listener
  35. wg sync.WaitGroup
  36. state state
  37. lock *sync.RWMutex
  38. BeforeBegin func(network, address string)
  39. OnShutdown func()
  40. }
  41. // NewServer creates a server on network at provided address
  42. func NewServer(network, address string) *Server {
  43. if GetManager().IsChild() {
  44. log.Info("Restarting new server: %s:%s on PID: %d", network, address, os.Getpid())
  45. } else {
  46. log.Info("Starting new server: %s:%s on PID: %d", network, address, os.Getpid())
  47. }
  48. srv := &Server{
  49. wg: sync.WaitGroup{},
  50. state: stateInit,
  51. lock: &sync.RWMutex{},
  52. network: network,
  53. address: address,
  54. }
  55. srv.BeforeBegin = func(network, addr string) {
  56. log.Debug("Starting server on %s:%s (PID: %d)", network, addr, syscall.Getpid())
  57. }
  58. return srv
  59. }
  60. // ListenAndServe listens on the provided network address and then calls Serve
  61. // to handle requests on incoming connections.
  62. func (srv *Server) ListenAndServe(serve ServeFunction) error {
  63. go srv.awaitShutdown()
  64. l, err := GetListener(srv.network, srv.address)
  65. if err != nil {
  66. log.Error("Unable to GetListener: %v", err)
  67. return err
  68. }
  69. srv.listener = newWrappedListener(l, srv)
  70. srv.BeforeBegin(srv.network, srv.address)
  71. return srv.Serve(serve)
  72. }
  73. // ListenAndServeTLS listens on the provided network address and then calls
  74. // Serve to handle requests on incoming TLS connections.
  75. //
  76. // Filenames containing a certificate and matching private key for the server must
  77. // be provided. If the certificate is signed by a certificate authority, the
  78. // certFile should be the concatenation of the server's certificate followed by the
  79. // CA's certificate.
  80. func (srv *Server) ListenAndServeTLS(certFile, keyFile string, serve ServeFunction) error {
  81. config := &tls.Config{}
  82. if config.NextProtos == nil {
  83. config.NextProtos = []string{"http/1.1"}
  84. }
  85. config.Certificates = make([]tls.Certificate, 1)
  86. certPEMBlock, err := ioutil.ReadFile(certFile)
  87. if err != nil {
  88. log.Error("Failed to load https cert file %s for %s:%s: %v", certFile, srv.network, srv.address, err)
  89. return err
  90. }
  91. keyPEMBlock, err := ioutil.ReadFile(keyFile)
  92. if err != nil {
  93. log.Error("Failed to load https key file %s for %s:%s: %v", keyFile, srv.network, srv.address, err)
  94. return err
  95. }
  96. config.Certificates[0], err = tls.X509KeyPair(certPEMBlock, keyPEMBlock)
  97. if err != nil {
  98. log.Error("Failed to create certificate from cert file %s and key file %s for %s:%s: %v", certFile, keyFile, srv.network, srv.address, err)
  99. return err
  100. }
  101. return srv.ListenAndServeTLSConfig(config, serve)
  102. }
  103. // ListenAndServeTLSConfig listens on the provided network address and then calls
  104. // Serve to handle requests on incoming TLS connections.
  105. func (srv *Server) ListenAndServeTLSConfig(tlsConfig *tls.Config, serve ServeFunction) error {
  106. go srv.awaitShutdown()
  107. l, err := GetListener(srv.network, srv.address)
  108. if err != nil {
  109. log.Error("Unable to get Listener: %v", err)
  110. return err
  111. }
  112. wl := newWrappedListener(l, srv)
  113. srv.listener = tls.NewListener(wl, tlsConfig)
  114. srv.BeforeBegin(srv.network, srv.address)
  115. return srv.Serve(serve)
  116. }
  117. // Serve accepts incoming HTTP connections on the wrapped listener l, creating a new
  118. // service goroutine for each. The service goroutines read requests and then call
  119. // handler to reply to them. Handler is typically nil, in which case the
  120. // DefaultServeMux is used.
  121. //
  122. // In addition to the standard Serve behaviour each connection is added to a
  123. // sync.Waitgroup so that all outstanding connections can be served before shutting
  124. // down the server.
  125. func (srv *Server) Serve(serve ServeFunction) error {
  126. defer log.Debug("Serve() returning... (PID: %d)", syscall.Getpid())
  127. srv.setState(stateRunning)
  128. GetManager().RegisterServer()
  129. err := serve(srv.listener)
  130. log.Debug("Waiting for connections to finish... (PID: %d)", syscall.Getpid())
  131. srv.wg.Wait()
  132. srv.setState(stateTerminate)
  133. GetManager().ServerDone()
  134. // use of closed means that the listeners are closed - i.e. we should be shutting down - return nil
  135. if err != nil && strings.Contains(err.Error(), "use of closed") {
  136. return nil
  137. }
  138. return err
  139. }
  140. func (srv *Server) getState() state {
  141. srv.lock.RLock()
  142. defer srv.lock.RUnlock()
  143. return srv.state
  144. }
  145. func (srv *Server) setState(st state) {
  146. srv.lock.Lock()
  147. defer srv.lock.Unlock()
  148. srv.state = st
  149. }
  150. type filer interface {
  151. File() (*os.File, error)
  152. }
  153. type wrappedListener struct {
  154. net.Listener
  155. stopped bool
  156. server *Server
  157. }
  158. func newWrappedListener(l net.Listener, srv *Server) *wrappedListener {
  159. return &wrappedListener{
  160. Listener: l,
  161. server: srv,
  162. }
  163. }
  164. func (wl *wrappedListener) Accept() (net.Conn, error) {
  165. var c net.Conn
  166. // Set keepalive on TCPListeners connections.
  167. if tcl, ok := wl.Listener.(*net.TCPListener); ok {
  168. tc, err := tcl.AcceptTCP()
  169. if err != nil {
  170. return nil, err
  171. }
  172. _ = tc.SetKeepAlive(true) // see http.tcpKeepAliveListener
  173. _ = tc.SetKeepAlivePeriod(3 * time.Minute) // see http.tcpKeepAliveListener
  174. c = tc
  175. } else {
  176. var err error
  177. c, err = wl.Listener.Accept()
  178. if err != nil {
  179. return nil, err
  180. }
  181. }
  182. c = wrappedConn{
  183. Conn: c,
  184. server: wl.server,
  185. }
  186. wl.server.wg.Add(1)
  187. return c, nil
  188. }
  189. func (wl *wrappedListener) Close() error {
  190. if wl.stopped {
  191. return syscall.EINVAL
  192. }
  193. wl.stopped = true
  194. return wl.Listener.Close()
  195. }
  196. func (wl *wrappedListener) File() (*os.File, error) {
  197. // returns a dup(2) - FD_CLOEXEC flag *not* set so the listening socket can be passed to child processes
  198. return wl.Listener.(filer).File()
  199. }
  200. type wrappedConn struct {
  201. net.Conn
  202. server *Server
  203. }
  204. func (w wrappedConn) Close() error {
  205. err := w.Conn.Close()
  206. if err == nil {
  207. w.server.wg.Done()
  208. }
  209. return err
  210. }