diff --git a/http.go b/http.go index 00992ba..2328150 100644 --- a/http.go +++ b/http.go @@ -27,13 +27,15 @@ func (c *Config) MarshalLogObject(e *log.Entry) { // Server is an wrapper for the *http.Server and *gin.Engine type Server struct { - http *http.Server - conf *Config - router *gin.Engine - config *toml.Tree - authhf auth.AuthenticationHandler - sites []Site - menus []menus.Menu + http *http.Server + conf *Config + router *gin.Engine + mrouter map[string]*gin.Engine + config *toml.Tree + authhf auth.AuthenticationHandler + sites []Site + menus []menus.Menu + NotFoundHandler gin.HandlerFunc } // StartServer starts the server as configured and sends the errormessage to the log. @@ -51,6 +53,19 @@ func (s *Server) StartServer() { } } +// DomainRouter redirects the requests to the routers of the domains +func (s *Server) DomainRouter(c *gin.Context) { + domain := c.Request.URL.Host + if router, found := s.mrouter[domain]; found { + router.NoMethod(s.NotFoundHandler) + router.NoRoute(s.NotFoundHandler) + c.Set("domain", domain) + router.HandleContext(c) + return + } + s.NotFoundHandler(c) +} + // CreateServer creates an server that can be run in a coroutine. func CreateServer(config *toml.Tree) *Server { log.Info().Msg("Redirect logging output to phuslu/log") @@ -61,16 +76,19 @@ func CreateServer(config *toml.Tree) *Server { conf: &Config{ Addr: "127.0.0.1:8080", }, - router: gin.New(), - authhf: &auth.AnonAccountHandler{}, + router: gin.New(), + mrouter: map[string]*gin.Engine{}, + authhf: &auth.AnonAccountHandler{}, } mw := []gin.HandlerFunc{ func(c *gin.Context) { c.Set(Accounts, server.authhf.Account(c)) c.Set(Menus, server.menus) }, + server.DomainRouter, } server.Use(mw...) + server.router.RouterGroup.Handlers = mw if err := config.Unmarshal(server.conf); err != nil { log.Error().Msg("Problem mapping config to Configstruct") } @@ -81,7 +99,7 @@ func CreateServer(config *toml.Tree) *Server { Handler: server.router, TLSConfig: server.conf.TLSconfig, } - server.router.NoRoute(gin.WrapH(http.NotFoundHandler())) + server.NotFoundHandler = gin.WrapH(http.NotFoundHandler()) gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) { log.Trace().Msgf("%-4s(%02d): %-20s %s", httpMethod, nuHandlers-len(mw), absolutePath, handlerName) } @@ -116,11 +134,17 @@ type Site interface { } // RegisterSite adds an site to the engine as its own grouo -func (s *Server) RegisterSite(path string, site Site) { - site.Init(s.router.Group(path)) +func (s *Server) RegisterSite(domain, path string, site Site) { + var router *gin.Engine + var found bool + if router, found = s.mrouter[domain]; !found { + router = gin.New() + s.mrouter[domain] = router + } + site.Init(router.Group(path)) s.sites = append(s.sites, site) if ms, ok := site.(menus.MenuSite); ok { - menus := ms.Menu() + menus := ms.Menu(domain) log.Debug().Msgf("%d menus are added", len(menus)) s.menus = append(s.menus, menus...) } diff --git a/menus/menus.go b/menus/menus.go index 3379182..ec4d2d9 100644 --- a/menus/menus.go +++ b/menus/menus.go @@ -37,7 +37,7 @@ type Menu interface { // MenuSite is an interface that is fullfilled by sites to return an type of menu. type MenuSite interface { - Menu() []Menu + Menu(string) []Menu } // MenuItem is an Implementation of the Menu Interface