support proxy prefix
This commit is contained in:
@@ -3,6 +3,7 @@ package ctrladmin
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"strings"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -80,6 +81,7 @@ func New(base *ctrlbase.Controller) *Controller {
|
||||
Funcs(sprig.FuncMap()).
|
||||
Funcs(template.FuncMap{
|
||||
"humanDate": humanize.Time,
|
||||
"path": base.Path,
|
||||
})
|
||||
tmplBase = extendFromPaths(tmplBase, prefixPartials)
|
||||
tmplBase = extendFromPaths(tmplBase, prefixLayouts)
|
||||
@@ -140,7 +142,11 @@ func (c *Controller) H(h adminHandler) http.Handler {
|
||||
}
|
||||
}
|
||||
if resp.redirect != "" {
|
||||
http.Redirect(w, r, resp.redirect, http.StatusSeeOther)
|
||||
to := resp.redirect
|
||||
if strings.HasPrefix(to, "/") {
|
||||
to = c.Path(to)
|
||||
}
|
||||
http.Redirect(w, r, to, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
if resp.err != "" {
|
||||
|
||||
@@ -36,7 +36,7 @@ func (c *Controller) ServeHome(r *http.Request) *Response {
|
||||
r.URL.Scheme,
|
||||
)
|
||||
host := firstExisting(
|
||||
"localhost:7373", // fallback
|
||||
"localhost:4747", // fallback
|
||||
r.Header.Get("X-Forwarded-Host"),
|
||||
r.Host,
|
||||
)
|
||||
|
||||
@@ -28,12 +28,12 @@ func (c *Controller) ServeLoginDo(w http.ResponseWriter, r *http.Request) {
|
||||
// session and put the row into the request context
|
||||
session.Values["user"] = user.Name
|
||||
sessLogSave(session, w, r)
|
||||
http.Redirect(w, r, "/admin/home", http.StatusSeeOther)
|
||||
http.Redirect(w, r, c.Path("/admin/home"), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func (c *Controller) ServeLogout(w http.ResponseWriter, r *http.Request) {
|
||||
session := r.Context().Value(CtxSession).(*sessions.Session)
|
||||
session.Options.MaxAge = -1
|
||||
sessLogSave(session, w, r)
|
||||
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
|
||||
http.Redirect(w, r, c.Path("/admin/login"), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func (c *Controller) WithUserSession(next http.Handler) http.Handler {
|
||||
if !ok {
|
||||
sessAddFlashW(session, []string{"you are not authenticated"})
|
||||
sessLogSave(session, w, r)
|
||||
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
|
||||
http.Redirect(w, r, c.Path("/admin/login"), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
// take username from sesion and add the user row to the context
|
||||
@@ -35,7 +35,7 @@ func (c *Controller) WithUserSession(next http.Handler) http.Handler {
|
||||
// user in the database (maybe the user was deleted)
|
||||
session.Options.MaxAge = -1
|
||||
sessLogSave(session, w, r)
|
||||
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
|
||||
http.Redirect(w, r, c.Path("/admin/login"), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
withUser := context.WithValue(r.Context(), CtxUser, user)
|
||||
@@ -51,7 +51,7 @@ func (c *Controller) WithAdminSession(next http.Handler) http.Handler {
|
||||
if !user.IsAdmin {
|
||||
sessAddFlashW(session, []string{"you are not an admin"})
|
||||
sessLogSave(session, w, r)
|
||||
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
|
||||
http.Redirect(w, r, c.Path("/admin/login"), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"senan.xyz/g/gonic/db"
|
||||
"senan.xyz/g/gonic/scanner"
|
||||
@@ -44,9 +45,15 @@ func statusToBlock(code int) string {
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
DB *db.DB
|
||||
MusicPath string
|
||||
Scanner *scanner.Scanner
|
||||
DB *db.DB
|
||||
MusicPath string
|
||||
Scanner *scanner.Scanner
|
||||
ProxyPrefix string
|
||||
}
|
||||
|
||||
// Path returns a URL path with the proxy prefix included
|
||||
func (c *Controller) Path(rel string) string {
|
||||
return path.Join(c.ProxyPrefix, rel)
|
||||
}
|
||||
|
||||
func (c *Controller) WithLogging(next http.Handler) http.Handler {
|
||||
|
||||
@@ -23,26 +23,28 @@ type Options struct {
|
||||
MusicPath string
|
||||
ListenAddr string
|
||||
ScanInterval time.Duration
|
||||
ProxyPrefix string
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
*http.Server
|
||||
router *mux.Router
|
||||
ctrlBase *ctrlbase.Controller
|
||||
opts Options
|
||||
router *mux.Router
|
||||
base *ctrlbase.Controller
|
||||
opts Options
|
||||
}
|
||||
|
||||
func New(opts Options) *Server {
|
||||
opts.MusicPath = filepath.Clean(opts.MusicPath)
|
||||
ctrlBase := &ctrlbase.Controller{
|
||||
DB: opts.DB,
|
||||
MusicPath: opts.MusicPath,
|
||||
Scanner: scanner.New(opts.DB, opts.MusicPath),
|
||||
base := &ctrlbase.Controller{
|
||||
DB: opts.DB,
|
||||
MusicPath: opts.MusicPath,
|
||||
Scanner: scanner.New(opts.DB, opts.MusicPath),
|
||||
ProxyPrefix: opts.ProxyPrefix,
|
||||
}
|
||||
router := mux.NewRouter()
|
||||
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// make the admin page the default
|
||||
http.Redirect(w, r, "/admin/home", http.StatusMovedPermanently)
|
||||
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
|
||||
@@ -50,11 +52,11 @@ func New(opts Options) *Server {
|
||||
// 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, redirectTo, http.StatusMovedPermanently)
|
||||
http.Redirect(w, r, base.Path(redirectTo), http.StatusMovedPermanently)
|
||||
})
|
||||
// common middleware for admin and subsonic routes
|
||||
router.Use(ctrlBase.WithLogging)
|
||||
router.Use(ctrlBase.WithCORS)
|
||||
router.Use(base.WithLogging)
|
||||
router.Use(base.WithCORS)
|
||||
server := &http.Server{
|
||||
Addr: opts.ListenAddr,
|
||||
Handler: router,
|
||||
@@ -63,15 +65,15 @@ func New(opts Options) *Server {
|
||||
IdleTimeout: 15 * time.Second,
|
||||
}
|
||||
return &Server{
|
||||
Server: server,
|
||||
router: router,
|
||||
ctrlBase: ctrlBase,
|
||||
opts: opts,
|
||||
Server: server,
|
||||
router: router,
|
||||
base: base,
|
||||
opts: opts,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) SetupAdmin() error {
|
||||
ctrl := ctrladmin.New(s.ctrlBase)
|
||||
ctrl := ctrladmin.New(s.base)
|
||||
//
|
||||
// begin public routes (creates session)
|
||||
routPublic := s.router.PathPrefix("/admin").Subrouter()
|
||||
@@ -119,7 +121,7 @@ func (s *Server) SetupAdmin() error {
|
||||
}
|
||||
|
||||
func (s *Server) SetupSubsonic() error {
|
||||
ctrl := ctrlsubsonic.New(s.ctrlBase)
|
||||
ctrl := ctrlsubsonic.New(s.base)
|
||||
rout := s.router.PathPrefix("/rest").Subrouter()
|
||||
rout.Use(ctrl.WithParams)
|
||||
rout.Use(ctrl.WithRequiredParams)
|
||||
@@ -167,7 +169,7 @@ func (s *Server) SetupSubsonic() error {
|
||||
func (s *Server) scanTick() {
|
||||
ticker := time.NewTicker(s.opts.ScanInterval)
|
||||
for range ticker.C {
|
||||
if err := s.ctrlBase.Scanner.Start(); err != nil {
|
||||
if err := s.base.Scanner.Start(); err != nil {
|
||||
log.Printf("error while scanner: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user