111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/gorilla/securecookie"
|
|
"github.com/zhang2092/mediahls/internal/db"
|
|
"github.com/zhang2092/mediahls/internal/pkg/config"
|
|
"github.com/zhang2092/mediahls/internal/pkg/logger"
|
|
"github.com/zhang2092/mediahls/internal/pkg/token"
|
|
)
|
|
|
|
type Server struct {
|
|
conf *config.Config
|
|
router *mux.Router
|
|
secureCookie *securecookie.SecureCookie
|
|
|
|
store db.Store
|
|
tokenMaker token.Maker
|
|
}
|
|
|
|
func NewServer(conf *config.Config, store db.Store) (*Server, error) {
|
|
tokenMaker, err := token.NewPasetoMaker(conf.TokenSymmetricKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot create token maker: %w", err)
|
|
}
|
|
|
|
hashKey := securecookie.GenerateRandomKey(32)
|
|
blockKey := securecookie.GenerateRandomKey(32)
|
|
secureCookie := securecookie.New(hashKey, blockKey)
|
|
secureCookie.MaxAge(7200)
|
|
|
|
server := &Server{
|
|
conf: conf,
|
|
secureCookie: secureCookie,
|
|
store: store,
|
|
tokenMaker: tokenMaker,
|
|
}
|
|
|
|
server.setupRouter()
|
|
return server, nil
|
|
}
|
|
|
|
func (server *Server) setupRouter() {
|
|
router := mux.NewRouter()
|
|
router.Use(mux.CORSMethodMiddleware(router))
|
|
router.PathPrefix("/statics/").Handler(http.StripPrefix("/statics/", http.FileServer(http.Dir("web/statics"))))
|
|
|
|
router.HandleFunc("/register", server.registerView).Methods(http.MethodGet)
|
|
router.HandleFunc("/register", server.register).Methods(http.MethodPost)
|
|
router.HandleFunc("/login", server.loginView).Methods(http.MethodGet)
|
|
router.HandleFunc("/login", server.login).Methods(http.MethodPost)
|
|
router.HandleFunc("/logout", server.logout).Methods(http.MethodGet)
|
|
router.HandleFunc("/", server.home).Methods(http.MethodGet)
|
|
router.HandleFunc("/play/{xid}", server.play).Methods(http.MethodGet)
|
|
router.HandleFunc("/media/{xid}/stream/", server.stream).Methods(http.MethodGet)
|
|
router.HandleFunc("/media/{xid}/stream/{segName:index[0-9]+.ts}", server.stream).Methods(http.MethodGet)
|
|
|
|
subRouter := router.PathPrefix("/").Subrouter()
|
|
subRouter.Use(server.authorizeMiddleware)
|
|
subRouter.HandleFunc("/upload", server.uploadView).Methods(http.MethodGet)
|
|
subRouter.HandleFunc("/upload", server.upload).Methods(http.MethodPost)
|
|
|
|
server.router = router
|
|
}
|
|
|
|
func (server *Server) Start(db *sql.DB) {
|
|
srv := &http.Server{
|
|
Addr: server.conf.ServerAddress,
|
|
Handler: server.router,
|
|
}
|
|
|
|
go func() {
|
|
log.Printf("server start on: %s\n", server.conf.ServerAddress)
|
|
if err := srv.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
|
|
log.Printf("listen: %s\n", err)
|
|
}
|
|
}()
|
|
|
|
quit := make(chan os.Signal, 1)
|
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|
<-quit
|
|
log.Println("Shutting down server...")
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
if err := db.Close(); err != nil {
|
|
log.Fatal("Server db to shutdown:", err)
|
|
}
|
|
if err := logger.Logger.Sync(); err != nil {
|
|
log.Fatal("Server log sync:", err)
|
|
}
|
|
|
|
if err := srv.Shutdown(ctx); err != nil {
|
|
log.Fatal("Server forced to shutdown:", err)
|
|
}
|
|
|
|
log.Println("Server exiting")
|
|
}
|