Files
gohoarder/pkg/server/server.go
T
2026-01-02 23:14:23 +00:00

131 lines
3.8 KiB
Go

package server
import (
"fmt"
"net/http"
"github.com/lukaszraczylo/gohoarder/pkg/config"
"github.com/lukaszraczylo/gohoarder/pkg/health"
"github.com/lukaszraczylo/gohoarder/pkg/logger"
"github.com/lukaszraczylo/gohoarder/pkg/metrics"
)
// Server wraps http.Server with configuration
type Server struct {
*http.Server
config *config.Config
healthChecker *health.Checker
}
// New creates a new HTTP server
func New(cfg *config.Config, healthChecker *health.Checker) (*Server, error) {
mux := http.NewServeMux()
// Register routes
registerRoutes(mux, cfg, healthChecker)
srv := &http.Server{
Addr: fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port),
Handler: logger.Middleware(mux),
ReadTimeout: cfg.Server.ReadTimeout,
WriteTimeout: cfg.Server.WriteTimeout,
IdleTimeout: cfg.Server.IdleTimeout,
}
return &Server{
Server: srv,
config: cfg,
healthChecker: healthChecker,
}, nil
}
// registerRoutes registers all HTTP routes
func registerRoutes(mux *http.ServeMux, cfg *config.Config, healthChecker *health.Checker) {
// Health endpoints
mux.HandleFunc("/health", healthChecker.HealthHandler())
mux.HandleFunc("/health/ready", healthChecker.ReadyHandler())
// Metrics endpoint
mux.Handle("/metrics", metrics.Handler())
// API endpoints
mux.HandleFunc("/api/v1/info", handleInfo(cfg))
// Package manager proxy endpoints (placeholders for now)
if cfg.Handlers.Go.Enabled {
mux.HandleFunc("/go/", handleGoProxy())
}
if cfg.Handlers.NPM.Enabled {
mux.HandleFunc("/npm/", handleNPMProxy())
}
if cfg.Handlers.PyPI.Enabled {
mux.HandleFunc("/pypi/", handlePyPIProxy())
}
// Root endpoint
mux.HandleFunc("/", handleRoot())
}
// handleInfo returns server information
func handleInfo(cfg *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
info := map[string]interface{}{
"name": "GoHoarder",
"version": "dev",
"handlers": map[string]bool{
"go": cfg.Handlers.Go.Enabled,
"npm": cfg.Handlers.NPM.Enabled,
"pypi": cfg.Handlers.PyPI.Enabled,
},
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, `{"success":true,"data":%v}`, toJSON(info))
}
}
// handleGoProxy handles Go module proxy requests
func handleGoProxy() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// TODO: Implement Go proxy handler
http.Error(w, `{"success":false,"error":{"code":"NOT_IMPLEMENTED","message":"Go proxy not yet implemented"}}`, http.StatusNotImplemented)
}
}
// handleNPMProxy handles NPM registry requests
func handleNPMProxy() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// TODO: Implement NPM proxy handler
http.Error(w, `{"success":false,"error":{"code":"NOT_IMPLEMENTED","message":"NPM proxy not yet implemented"}}`, http.StatusNotImplemented)
}
}
// handlePyPIProxy handles PyPI requests
func handlePyPIProxy() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// TODO: Implement PyPI proxy handler
http.Error(w, `{"success":false,"error":{"code":"NOT_IMPLEMENTED","message":"PyPI proxy not yet implemented"}}`, http.StatusNotImplemented)
}
}
// handleRoot handles root path
func handleRoot() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, `{"success":true,"data":{"message":"GoHoarder - Universal Package Cache Proxy","docs":"https://github.com/lukaszraczylo/gohoarder"}}`)
}
}
// toJSON is a simple JSON encoder (replace with proper implementation)
func toJSON(v interface{}) string {
// Simplified for now - proper implementation would use goccy/go-json
return fmt.Sprintf("%v", v)
}