Files
ddc/internal/server/server.go
T

79 lines
2.4 KiB
Go
Executable File

package server
import (
"net/http"
"strings"
"time"
"ddc/internal/auth"
"ddc/internal/config"
"ddc/internal/jobs"
"ddc/web"
)
const (
maxLoginFailures = 5
loginLockout = 15 * time.Minute
)
type Server struct {
settings config.Settings
sessions *auth.SessionStore
limiter *auth.LoginLimiter
manager *jobs.Manager
}
func New(settings config.Settings, sessions *auth.SessionStore, manager *jobs.Manager) http.Handler {
server := &Server{
settings: settings,
sessions: sessions,
limiter: auth.NewLoginLimiter(maxLoginFailures, loginLockout),
manager: manager,
}
return server.routes()
}
func (server *Server) routes() http.Handler {
api := http.NewServeMux()
api.HandleFunc("POST /api/logout", server.handleLogout)
api.HandleFunc("GET /api/libraries", server.handleLibraries)
api.HandleFunc("GET /api/disk", server.handleDisk)
api.HandleFunc("GET /api/settings", server.handleGetSettings)
api.HandleFunc("POST /api/settings", server.handleUpdateSettings)
api.HandleFunc("GET /api/jobs", server.handleListJobs)
api.HandleFunc("POST /api/jobs", server.handleCreateJob)
api.HandleFunc("GET /api/jobs/{id}/files", server.handleJobFiles)
api.HandleFunc("POST /api/jobs/{id}/extract", server.handleExtract)
api.HandleFunc("POST /api/jobs/{id}/move", server.handleMove)
api.HandleFunc("POST /api/jobs/{id}/pause", server.handlePause)
api.HandleFunc("POST /api/jobs/{id}/resume", server.handleResume)
api.HandleFunc("POST /api/jobs/{id}/queue", server.handleReorder)
api.HandleFunc("DELETE /api/jobs/{id}", server.handleDeleteJob)
api.HandleFunc("GET /api/history", server.handleHistory)
api.HandleFunc("DELETE /api/history", server.handleClearHistory)
root := http.NewServeMux()
root.HandleFunc("POST /api/login", server.handleLogin)
root.HandleFunc("GET /api/session", server.handleSession)
root.HandleFunc("GET /healthz", handleHealth)
root.Handle("/api/", server.requireSession(api))
root.Handle("/", staticHandler())
return securityHeaders(protectStateChanges(root))
}
func staticHandler() http.Handler {
fileServer := http.FileServerFS(web.Static())
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if request.URL.Path != "/" && strings.HasSuffix(request.URL.Path, "/") {
http.NotFound(writer, request)
return
}
fileServer.ServeHTTP(writer, request)
})
}
func handleHealth(writer http.ResponseWriter, _ *http.Request) {
writer.WriteHeader(http.StatusNoContent)
}