Files
spore-registry/internal/app/app.go
2025-10-21 22:43:18 +02:00

110 lines
2.9 KiB
Go

package app
import (
"fmt"
"log"
"net/http"
"os"
"github.com/rs/cors"
"spore-registry/internal/config"
"spore-registry/internal/database"
"spore-registry/internal/handlers"
"spore-registry/internal/repository"
"spore-registry/internal/service"
"spore-registry/internal/storage"
)
// App holds the application dependencies
type App struct {
config *config.Config
db *database.DB
handler *handlers.FirmwareHandler
}
// NewApp creates a new application instance
func NewApp() (*App, error) {
// Load configuration
cfg := config.LoadConfig()
// Create registry directory if it doesn't exist
if err := os.MkdirAll(cfg.Registry, 0755); err != nil {
return nil, fmt.Errorf("failed to create registry directory: %w", err)
}
// Initialize database
db, err := database.NewDB(cfg.DBPath)
if err != nil {
return nil, fmt.Errorf("failed to initialize database: %w", err)
}
// Create repository
repo := repository.NewFirmwareRepository(db.GetConnection())
// Create storage
fileStorage := storage.NewFileStorage(cfg.Registry)
// Create service
firmwareService := service.NewFirmwareService(repo, fileStorage)
// Create handler
handler := handlers.NewFirmwareHandler(firmwareService)
return &App{
config: cfg,
db: db,
handler: handler,
}, nil
}
// Close closes the database connection
func (a *App) Close() error {
return a.db.Close()
}
// SetupRoutes sets up HTTP routes
func (a *App) SetupRoutes() *http.ServeMux {
mux := http.NewServeMux()
// API endpoints
mux.HandleFunc("POST /firmware", a.handler.UploadFirmware)
mux.HandleFunc("PUT /firmware/{name}/{version}", a.handler.UpdateFirmwareMetadata)
mux.HandleFunc("GET /firmware", a.handler.ListFirmware)
mux.HandleFunc("GET /firmware/{name}/{version}", a.handler.DownloadFirmware)
// Health check endpoint
mux.HandleFunc("GET /health", a.handler.HealthCheck)
return mux
}
// Start starts the HTTP server
func (a *App) Start() error {
mux := a.SetupRoutes()
log.Printf("Starting SPORE registry server on port %s", a.config.Port)
log.Printf("Server will be accessible from any host on port %s", a.config.Port)
log.Printf("CORS enabled for all origins to support mobile access")
// Add CORS middleware with dynamic origin handling
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"}, // Allow all origins for mobile access
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"*"},
AllowCredentials: false, // Set to false when using wildcard origins
AllowOriginFunc: func(origin string) bool {
// Allow all origins for mobile/remote access
return true
},
})
// Add request logging middleware
loggedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s from %s", r.Method, r.URL.Path, r.RemoteAddr)
c.Handler(mux).ServeHTTP(w, r)
})
return http.ListenAndServe(":"+a.config.Port, loggedHandler)
}