server.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package server
  2. import (
  3. "context"
  4. "log/slog"
  5. "net/http"
  6. "os"
  7. "os/user"
  8. "path/filepath"
  9. "github.com/ncarlier/webhookd/pkg/api"
  10. "github.com/ncarlier/webhookd/pkg/config"
  11. "golang.org/x/crypto/acme/autocert"
  12. )
  13. func cacheDir() (dir string) {
  14. if u, _ := user.Current(); u != nil {
  15. dir = filepath.Join(os.TempDir(), "webhookd-acme-cache-"+u.Username)
  16. if err := os.MkdirAll(dir, 0o700); err == nil {
  17. return dir
  18. }
  19. }
  20. return ""
  21. }
  22. // Server is a HTTP server wrapper used to manage TLS
  23. type Server struct {
  24. self *http.Server
  25. tls bool
  26. certFile string
  27. keyFile string
  28. }
  29. // ListenAndServe start HTTP(s) server
  30. func (s *Server) ListenAndServe() error {
  31. if s.tls {
  32. return s.self.ListenAndServeTLS(s.certFile, s.keyFile)
  33. }
  34. return s.self.ListenAndServe()
  35. }
  36. // Shutdown stop HTTP(s) server
  37. func (s *Server) Shutdown(ctx context.Context) error {
  38. s.self.SetKeepAlivesEnabled(false)
  39. return s.self.Shutdown(ctx)
  40. }
  41. // NewServer create new HTTP(s) server
  42. func NewServer(cfg *config.Config) *Server {
  43. logger := slog.NewLogLogger(slog.Default().Handler(), slog.LevelError)
  44. server := &Server{
  45. tls: cfg.TLS.Enabled,
  46. self: &http.Server{
  47. Addr: cfg.ListenAddr,
  48. Handler: api.NewRouter(cfg),
  49. ErrorLog: logger,
  50. },
  51. }
  52. if server.tls {
  53. // HTTPs server
  54. if cfg.TLS.Domain == "" {
  55. server.certFile = cfg.TLS.CertFile
  56. server.keyFile = cfg.TLS.KeyFile
  57. } else {
  58. m := &autocert.Manager{
  59. Cache: autocert.DirCache(cacheDir()),
  60. Prompt: autocert.AcceptTOS,
  61. HostPolicy: autocert.HostWhitelist(cfg.TLS.Domain),
  62. }
  63. server.self.TLSConfig = m.TLSConfig()
  64. server.certFile = ""
  65. server.keyFile = ""
  66. }
  67. }
  68. return server
  69. }