http.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package config
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "net/http"
  6. "time"
  7. "github.com/logrusorgru/aurora/v4"
  8. "golang.org/x/sync/errgroup"
  9. "m7s.live/engine/v4/log"
  10. "m7s.live/engine/v4/util"
  11. )
  12. var _ HTTPConfig = (*HTTP)(nil)
  13. type Middleware func(string, http.Handler) http.Handler
  14. type HTTP struct {
  15. ListenAddr string `desc:"监听地址"`
  16. ListenAddrTLS string `desc:"监听地址HTTPS"`
  17. CertFile string `desc:"HTTPS证书文件"`
  18. KeyFile string `desc:"HTTPS密钥文件"`
  19. CORS bool `default:"true" desc:"是否自动添加CORS头"` //是否自动添加CORS头
  20. UserName string `desc:"基本身份认证用户名"`
  21. Password string `desc:"基本身份认证密码"`
  22. ReadTimeout time.Duration `desc:"读取超时"`
  23. WriteTimeout time.Duration `desc:"写入超时"`
  24. IdleTimeout time.Duration `desc:"空闲超时"`
  25. mux *http.ServeMux
  26. middlewares []Middleware
  27. }
  28. type HTTPConfig interface {
  29. GetHTTPConfig() *HTTP
  30. Listen(ctx context.Context) error
  31. Handle(string, http.Handler)
  32. Handler(*http.Request) (http.Handler, string)
  33. AddMiddleware(Middleware)
  34. }
  35. func (config *HTTP) AddMiddleware(middleware Middleware) {
  36. config.middlewares = append(config.middlewares, middleware)
  37. }
  38. func (config *HTTP) Handle(path string, f http.Handler) {
  39. if config.mux == nil {
  40. config.mux = http.NewServeMux()
  41. }
  42. if config.CORS {
  43. f = util.CORS(f)
  44. }
  45. if config.UserName != "" && config.Password != "" {
  46. f = util.BasicAuth(config.UserName, config.Password, f)
  47. }
  48. for _, middleware := range config.middlewares {
  49. f = middleware(path, f)
  50. }
  51. config.mux.Handle(path, f)
  52. }
  53. func (config *HTTP) GetHTTPConfig() *HTTP {
  54. return config
  55. }
  56. func (config *HTTP) Handler(r *http.Request) (h http.Handler, pattern string) {
  57. return config.mux.Handler(r)
  58. }
  59. // ListenAddrs Listen http and https
  60. func (config *HTTP) Listen(ctx context.Context) error {
  61. if config.mux == nil {
  62. return nil
  63. }
  64. var g errgroup.Group
  65. if config.ListenAddrTLS != "" && (config == &Global.HTTP || config.ListenAddrTLS != Global.ListenAddrTLS) {
  66. g.Go(func() error {
  67. if Global.LogLang == "zh" {
  68. log.Info("🌐 https 监听在 ", aurora.Blink(config.ListenAddrTLS))
  69. } else {
  70. log.Info("🌐 https listen at ", aurora.Blink(config.ListenAddrTLS))
  71. }
  72. cer, _ := tls.X509KeyPair(LocalCert, LocalKey)
  73. var server = http.Server{
  74. Addr: config.ListenAddrTLS,
  75. ReadTimeout: config.ReadTimeout,
  76. WriteTimeout: config.WriteTimeout,
  77. IdleTimeout: config.IdleTimeout,
  78. Handler: config.mux,
  79. TLSConfig: &tls.Config{
  80. Certificates: []tls.Certificate{cer},
  81. CipherSuites: []uint16{
  82. tls.TLS_AES_128_GCM_SHA256,
  83. tls.TLS_CHACHA20_POLY1305_SHA256,
  84. tls.TLS_AES_256_GCM_SHA384,
  85. //tls.TLS_RSA_WITH_AES_128_CBC_SHA,
  86. //tls.TLS_RSA_WITH_AES_256_CBC_SHA,
  87. //tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
  88. //tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
  89. tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
  90. tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
  91. tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  92. tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  93. tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
  94. tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
  95. tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
  96. tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
  97. tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
  98. tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
  99. tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
  100. tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
  101. },
  102. },
  103. }
  104. return server.ListenAndServeTLS(config.CertFile, config.KeyFile)
  105. })
  106. }
  107. if config.ListenAddr != "" && (config == &Global.HTTP || config.ListenAddr != Global.ListenAddr) {
  108. g.Go(func() error {
  109. if Global.LogLang == "zh" {
  110. log.Info("🌐 http 监听在 ", aurora.Blink(config.ListenAddr))
  111. } else {
  112. log.Info("🌐 http listen at ", aurora.Blink(config.ListenAddr))
  113. }
  114. var server = http.Server{
  115. Addr: config.ListenAddr,
  116. ReadTimeout: config.ReadTimeout,
  117. WriteTimeout: config.WriteTimeout,
  118. IdleTimeout: config.IdleTimeout,
  119. Handler: config.mux,
  120. }
  121. return server.ListenAndServe()
  122. })
  123. }
  124. g.Go(func() error {
  125. <-ctx.Done()
  126. return ctx.Err()
  127. })
  128. return g.Wait()
  129. }