110 lines
2.9 KiB
Go
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)
|
|
}
|