github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/web/web.go (about) 1 package web 2 3 import ( 4 "context" 5 "net/http" 6 "strconv" 7 "time" 8 9 "github.com/ShoshinNikita/budget-manager/internal/logger" 10 "github.com/ShoshinNikita/budget-manager/internal/pkg/errors" 11 "github.com/ShoshinNikita/budget-manager/internal/web/api" 12 "github.com/ShoshinNikita/budget-manager/internal/web/middlewares" 13 "github.com/ShoshinNikita/budget-manager/internal/web/pages" 14 "github.com/ShoshinNikita/budget-manager/static" 15 ) 16 17 type Server struct { 18 config Config 19 log logger.Logger 20 db Database 21 22 server *http.Server 23 24 version string 25 gitHash string 26 } 27 28 type Database interface { 29 api.DB 30 pages.DB 31 } 32 33 func NewServer(cfg Config, db Database, log logger.Logger, version, gitHash string) *Server { 34 s := &Server{ 35 config: cfg, 36 db: db, 37 log: log, 38 // 39 version: version, 40 gitHash: gitHash, 41 } 42 s.server = &http.Server{ 43 Addr: ":" + strconv.Itoa(cfg.Port), 44 Handler: s.buildServerHandler(), 45 } 46 47 return s 48 } 49 50 func (s *Server) buildServerHandler() http.Handler { 51 router := http.NewServeMux() 52 53 if !s.config.UseEmbed { 54 s.log.Warn("don't use embedded templates and static files") 55 } 56 57 // Add API routes 58 s.addRoutes(router) 59 if s.config.EnableProfiling { 60 // Enable pprof handlers 61 s.log.Warn("pprof handlers are enabled") 62 s.addPprofRoutes(router) 63 } 64 65 // Add File Handler 66 fs := http.FS(static.New(s.config.UseEmbed)) 67 fileHandler := http.StripPrefix("/static/", http.FileServer(fs)) 68 fileHandler = middlewares.CachingMiddleware(fileHandler, time.Hour*24*30, s.gitHash) // cache for 1 month 69 router.Handle("/static/", fileHandler) 70 71 // Wrap the handler in middlewares. The last middleware will be called first and so on 72 var handler http.Handler = router 73 if !s.config.Auth.Disable { 74 handler = middlewares.BasicAuthMiddleware(handler, s.config.Auth.BasicAuthCreds, s.log) 75 if len(s.config.Auth.BasicAuthCreds) == 0 { 76 s.log.Warn("auth is enabled, but list of creds is empty") 77 } 78 } else { 79 s.log.Warn("auth is disabled") 80 } 81 handler = middlewares.LoggingMiddleware(handler, s.log) 82 handler = middlewares.RequestIDMeddleware(handler) 83 84 return handler 85 } 86 87 func (s Server) ListenAndServer() error { 88 s.log.Debug("start server") 89 90 if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { 91 return errors.Wrap(err, "server error") 92 } 93 94 return nil 95 } 96 97 func (s Server) Shutdown() error { 98 ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 99 defer cancel() 100 101 return s.server.Shutdown(ctx) 102 }