refactor server creation

This commit is contained in:
sentriz
2020-02-21 01:19:21 +00:00
parent b677af43f0
commit e9ca7fba64
2 changed files with 43 additions and 47 deletions

View File

@@ -55,12 +55,6 @@ func main() {
} }
log.Printf("using opts %+v\n", serverOptions) log.Printf("using opts %+v\n", serverOptions)
s := server.New(serverOptions) s := server.New(serverOptions)
if err = s.SetupAdmin(); err != nil {
log.Fatalf("error setting up admin routes: %v\n", err)
}
if err = s.SetupSubsonic(); err != nil {
log.Fatalf("error setting up subsonic routes: %v\n", err)
}
log.Printf("starting server at %s", *listenAddr) log.Printf("starting server at %s", *listenAddr)
if err := s.Start(); err != nil { if err := s.Start(); err != nil {
log.Fatalf("error starting server: %v\n", err) log.Fatalf("error starting server: %v\n", err)

View File

@@ -28,35 +28,29 @@ type Options struct {
type Server struct { type Server struct {
*http.Server *http.Server
router *mux.Router scanner *scanner.Scanner
base *ctrlbase.Controller scanInterval time.Duration
opts Options
} }
func New(opts Options) *Server { func New(opts Options) *Server {
// ** begin sanitation
opts.MusicPath = filepath.Clean(opts.MusicPath) opts.MusicPath = filepath.Clean(opts.MusicPath)
// ** begin controllers
scanner := scanner.New(opts.DB, opts.MusicPath)
base := &ctrlbase.Controller{ base := &ctrlbase.Controller{
DB: opts.DB, DB: opts.DB,
MusicPath: opts.MusicPath, MusicPath: opts.MusicPath,
Scanner: scanner.New(opts.DB, opts.MusicPath),
ProxyPrefix: opts.ProxyPrefix, ProxyPrefix: opts.ProxyPrefix,
Scanner: scanner,
} }
// router with common wares for admin / subsonic
router := mux.NewRouter() router := mux.NewRouter()
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// make the admin page the default
http.Redirect(w, r, base.Path("/admin/home"), http.StatusMovedPermanently)
})
router.HandleFunc("/musicFolderSettings.view", func(w http.ResponseWriter, r *http.Request) {
// jamstash seems to call "musicFolderSettings.view" to start a scan. notice
// that there is no "/rest/" prefix, so i doesn't fit in with the nice router,
// custom handler, middleware. etc setup that we've got in `SetupSubsonic()`.
// instead lets redirect to down there and use the scan endpoint
redirectTo := fmt.Sprintf("/rest/startScan.view?%s", r.URL.Query().Encode())
http.Redirect(w, r, base.Path(redirectTo), http.StatusMovedPermanently)
})
// common middleware for admin and subsonic routes
router.Use(base.WithLogging) router.Use(base.WithLogging)
router.Use(base.WithCORS) router.Use(base.WithCORS)
setupMisc(router, base)
setupAdmin(router, ctrladmin.New(base))
setupSubsonic(router, ctrlsubsonic.New(base))
//
server := &http.Server{ server := &http.Server{
Addr: opts.ListenAddr, Addr: opts.ListenAddr,
Handler: router, Handler: router,
@@ -66,16 +60,29 @@ func New(opts Options) *Server {
} }
return &Server{ return &Server{
Server: server, Server: server,
router: router, scanner: scanner,
base: base, scanInterval: opts.ScanInterval,
opts: opts,
} }
} }
func (s *Server) SetupAdmin() error { func setupMisc(router *mux.Router, ctrl *ctrlbase.Controller) {
ctrl := ctrladmin.New(s.base) router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// make the admin page the default
http.Redirect(w, r, ctrl.Path("/admin/home"), http.StatusMovedPermanently)
})
router.HandleFunc("/musicFolderSettings.view", func(w http.ResponseWriter, r *http.Request) {
// jamstash seems to call "musicFolderSettings.view" to start a scan. notice
// that there is no "/rest/" prefix, so i doesn't fit in with the nice router,
// custom handler, middleware. etc setup that we've got in `SetupSubsonic()`.
// instead lets redirect to down there and use the scan endpoint
redirectTo := fmt.Sprintf("/rest/startScan.view?%s", r.URL.Query().Encode())
http.Redirect(w, r, ctrl.Path(redirectTo), http.StatusMovedPermanently)
})
}
func setupAdmin(router *mux.Router, ctrl *ctrladmin.Controller) {
// ** begin public routes (creates session) // ** begin public routes (creates session)
routPublic := s.router.PathPrefix("/admin").Subrouter() routPublic := router.PathPrefix("/admin").Subrouter()
routPublic.Use(ctrl.WithSession) routPublic.Use(ctrl.WithSession)
routPublic.Handle("/login", ctrl.H(ctrl.ServeLogin)) routPublic.Handle("/login", ctrl.H(ctrl.ServeLogin))
routPublic.HandleFunc("/login_do", ctrl.ServeLoginDo) // "raw" handler, updates session routPublic.HandleFunc("/login_do", ctrl.ServeLoginDo) // "raw" handler, updates session
@@ -114,12 +121,10 @@ func (s *Server) SetupAdmin() error {
notFoundHandler := ctrl.H(ctrl.ServeNotFound) notFoundHandler := ctrl.H(ctrl.ServeNotFound)
notFoundRoute := routPublic.NewRoute().Handler(notFoundHandler) notFoundRoute := routPublic.NewRoute().Handler(notFoundHandler)
routPublic.NotFoundHandler = notFoundRoute.GetHandler() routPublic.NotFoundHandler = notFoundRoute.GetHandler()
return nil
} }
func (s *Server) SetupSubsonic() error { func setupSubsonic(router *mux.Router, ctrl *ctrlsubsonic.Controller) {
ctrl := ctrlsubsonic.New(s.base) rout := router.PathPrefix("/rest").Subrouter()
rout := s.router.PathPrefix("/rest").Subrouter()
rout.Use(ctrl.WithParams) rout.Use(ctrl.WithParams)
rout.Use(ctrl.WithRequiredParams) rout.Use(ctrl.WithRequiredParams)
rout.Use(ctrl.WithUser) rout.Use(ctrl.WithUser)
@@ -162,22 +167,19 @@ func (s *Server) SetupSubsonic() error {
notFoundHandler := ctrl.H(ctrl.ServeNotFound) notFoundHandler := ctrl.H(ctrl.ServeNotFound)
notFoundRoute := rout.NewRoute().Handler(notFoundHandler) notFoundRoute := rout.NewRoute().Handler(notFoundHandler)
rout.NotFoundHandler = notFoundRoute.GetHandler() rout.NotFoundHandler = notFoundRoute.GetHandler()
return nil
}
func (s *Server) scanTick() {
ticker := time.NewTicker(s.opts.ScanInterval)
for range ticker.C {
if err := s.base.Scanner.Start(); err != nil {
log.Printf("error while scanner: %v", err)
}
}
} }
func (s *Server) Start() error { func (s *Server) Start() error {
if s.opts.ScanInterval > 0 { if s.scanInterval > 0 {
log.Printf("will be scanning at intervals of %s", s.opts.ScanInterval) log.Printf("will be scanning at intervals of %s", s.scanInterval)
go s.scanTick() ticker := time.NewTicker(s.scanInterval)
go func() {
for range ticker.C {
if err := s.scanner.Start(); err != nil {
log.Printf("error while scanner: %v", err)
}
}
}()
} }
return s.ListenAndServe() return s.ListenAndServe()
} }