diff --git a/main.go b/main.go index 6eaa582..b6a5f2e 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,9 @@ package main import ( "context" + "errors" "fmt" + "net/http" "os" "git.t-juice.club/torjus/ministream/server" @@ -11,20 +13,29 @@ import ( const Version = "v0.1.1" +type ctxKey string + +const ( + ctxKeyConfig ctxKey = "config" +) + func main() { app := cli.App{ Name: "ministream", Usage: "Small livestreaming platform.", Commands: []*cli.Command{ { - Name: "serve", - Usage: "Start livestreaming server.", - Action: func(ctx *cli.Context) error { - store := server.NewUserStore() + Name: "serve", + Usage: "Start livestreaming server.", + Before: loadConfig, + Action: func(c *cli.Context) error { + cfg := configFromCtx(c.Context) - srv := server.NewServer(store) - srv.Addr = ":8080" - srv.ListenAndServe() + srv := server.NewServer(cfg) + srv.Addr = cfg.HTTPListenAddr + if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + return err + } return nil }, }, @@ -37,3 +48,27 @@ func main() { fmt.Println(err) } } + +func loadConfig(c *cli.Context) error { + cfg, err := server.ConfigFromDefault() + if err != nil { + return err + } + + c.Context = context.WithValue(c.Context, ctxKeyConfig, cfg) + return nil +} + +func configFromCtx(ctx context.Context) *server.Config { + value := ctx.Value(ctxKeyConfig) + if value == nil { + panic("unable to load config") + } + + config, ok := value.(*server.Config) + if !ok { + panic("config type assertion failed") + } + + return config +} diff --git a/server/server.go b/server/server.go index bb8e588..f1608fe 100644 --- a/server/server.go +++ b/server/server.go @@ -19,15 +19,15 @@ import ( var static embed.FS type Server struct { - users *UserStore streams *StreamStore + config *Config http.Server } -func NewServer(store *UserStore) *Server { +func NewServer(config *Config) *Server { srv := &Server{ - users: store, streams: NewStreamStore(), + config: config, } r := chi.NewRouter() @@ -41,6 +41,7 @@ func NewServer(store *UserStore) *Server { r.Patch("/whip/{streamKey}", srv.PatchHandler) r.Post("/whip/{streamKey}", srv.PostOfferHandler) r.Get("/stats", srv.streams.StatsHandler) + r.Get("/api/siteinfo", srv.InfoHandler) srv.Handler = r @@ -55,6 +56,17 @@ func corsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(fn) } +func (s *Server) InfoHandler(w http.ResponseWriter, r *http.Request) { + var infoResponse struct { + SiteName string `json:"siteName"` + } + infoResponse.SiteName = s.config.SiteName + + if err := json.NewEncoder(w).Encode(&infoResponse); err != nil { + slog.Warn("Error writing info response") + } +} + func (s *Server) OptionsHandler(w http.ResponseWriter, r *http.Request) { slog.Info("Got OPTIONS") }