diff --git a/http.go b/http.go index efc46f8..02c1d7f 100644 --- a/http.go +++ b/http.go @@ -12,6 +12,7 @@ import ( "github.com/flosch/pongo2/v6" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" + "go.sebtobie.de/generic" "go.sebtobie.de/httpserver/auth" "go.sebtobie.de/httpserver/constants" "go.sebtobie.de/httpserver/funcs" @@ -52,11 +53,12 @@ type Server struct { authh auth.AuthenticationHandler middleware gin.HandlersChain advmiddleware map[string]middleware.Middleware + alldomainsites []Site } // CreateServer creates an server that can be run in a coroutine. func CreateServer() *Server { - log.Info().Msg("Redirect logging output to phuslu/log") + log.Info().Msg("Redirect logging output to zerolog") gin.DefaultErrorWriter = log.Logger.With().Str("source", "GIN").Logger() gin.DefaultWriter = log.Logger.With().Str("source", "GIN").Logger() log.Info().Msg("Creating HTTP-Server") @@ -74,6 +76,7 @@ func CreateServer() *Server { middleware: gin.HandlersChain{}, template: pongo2.NewSet("templates", &templates.EmptyLoader{}), advmiddleware: map[string]middleware.Middleware{}, + alldomainsites: []Site{}, } server.http = &http.Server{ ErrorLog: intlog.New(log.Logger, "", 0), @@ -131,13 +134,13 @@ func (s *Server) StartServer() { log.Info().Msg("Starting server") s.http.TLSConfig = s.Conf.TLSconfig if s.Conf.Certfile != "" && s.Conf.Keyfile != "" { + s.routines.Add(len(s.Conf.TLSAddr)) for _, addr := range s.Conf.TLSAddr { - s.routines.Add(1) go s.runPort(addr, true) } } + s.routines.Add(len(s.Conf.Addr)) for _, addr := range s.Conf.Addr { - s.routines.Add(1) go s.runPort(addr, false) } s.routines.Wait() @@ -155,9 +158,11 @@ func (s *Server) DomainRouter(w http.ResponseWriter, r *http.Request) { } r.Host = domain r.URL.Host = domain + trch := log.Trace() for header, value := range map[string][]string(r.Header) { - log.Trace().Strs(header, value).Msg("Headers") + trch.Strs(header, value) } + trch.Msg("Headers") if router, found := s.mrouter[domain]; found { router.NoMethod(gin.WrapH(s.NotFoundHandler)) router.NoRoute(gin.WrapH(s.NotFoundHandler)) @@ -203,6 +208,29 @@ func maptoarray(m map[string]Site) (a []any) { return } +func (s *Server) newrouter(domain string) *gin.Engine { + log.Info().Msgf("Setting up router for %s", domain) + router := gin.New() + router.Use(func(c *gin.Context) { + c.Set(constants.Domain, domain) + c.Set(constants.Menus, s.menus) + c.Set(constants.Accounts, s.authh.Account(c)) + }) + router.Use(s.middleware...) + router.HTMLRender = templates.NewPongo2Renderer(s.template) + s.mrouter[domain] = router + for _, site := range s.alldomainsites { + site.Init(router.Group("/")) + } + return router +} + +func unequal[T comparable](i T) func(t T) bool { + return func(t T) bool { + return t != i + } +} + // Setup sets the server up. It loads the sites and prepare the server for startup. // The Midleware and the site are setup in this Order: // 1. Middleware.Setup @@ -220,26 +248,37 @@ func (s *Server) Setup() { for cfg, m := range s.advmiddleware { m.Setup(s.Conf.Middleware[cfg]) } + var config SiteConfig + var err error for cfg, site = range s.sites { - config := s.Conf.Sites[cfg] - if router, found = s.mrouter[config["domain"].(string)]; !found { - log.Info().Msgf("Setting up router for %s", config["domain"].(string)) - router = gin.New() - router.Use(func(c *gin.Context) { - c.Set(constants.Domain, config["domain"]) - c.Set(constants.Menus, s.menus) - c.Set(constants.Accounts, s.authh.Account(c)) - }) - router.Use(s.middleware...) - router.HTMLRender = templates.NewPongo2Renderer(s.template) - s.mrouter[config["domain"].(string)] = router + config, found = s.Conf.Sites[cfg] + var domain = "*" + var path = "/" + if found { + if generic.Valid(config["domain"], unequal("")) { + domain = config["domain"].(string) + } + if generic.Valid(config["path"], unequal("")) { + path = config["path"].(string) + } + } + log.Debug().Str("domain", domain).Str("path", path).Msgf("setting up site %s", cfg) + if domain != "*" { + if router, found = s.mrouter[domain]; !found { + router = s.newrouter(domain) + } + group := router.Group(config["path"].(string)) + site.Init(group) + } else { + s.alldomainsites = append(s.alldomainsites, site) + for _, router = range s.mrouter { + site.Init(router.Group(path)) + } } - group := router.Group(config["path"].(string)) - site.Init(group) } for _, m := range s.advmiddleware { if psm, ok := m.(middleware.PreSetupMiddleware); ok { - if err := psm.PreSetup(maptoarray(s.sites)); err != nil { + if err = psm.PreSetup(maptoarray(s.sites)); err != nil { log.Error().Err(err).Msg("Failed to setup midddleware (pre-site-setup). Stopping with the setup") return } @@ -261,12 +300,14 @@ func (s *Server) Setup() { } } if cs, ok := site.(ConfigSite); ok { - cs.Setup(config) + if err = cs.Setup(config); err != nil { + log.Error().Err(err).Msgf("Failed to setup site with config %s", cfg) + } } } for _, m := range s.advmiddleware { if psm, ok := m.(middleware.PostSetupMiddleware); ok { - if err := psm.PostSetup(maptoarray(s.sites)); err != nil { + if err = psm.PostSetup(maptoarray(s.sites)); err != nil { log.Error().Err(err).Msg("Failed to setup midddleware (post-site-setup). Stopping with the setup") return }