package server import ( "context" "fmt" "net/http" "time" "github.com/YspCoder/clawgo/pkg/config" "github.com/YspCoder/clawgo/pkg/logger" ) type Server struct { server *http.Server config *config.Config } func NewServer(cfg *config.Config) *Server { return &Server{ config: cfg, } } func (s *Server) Start() error { mux := http.NewServeMux() mux.HandleFunc("/health", s.handleHealth) mux.HandleFunc("/", s.handleRoot) addr := fmt.Sprintf("%s:%d", s.config.Gateway.Host, s.config.Gateway.Port) s.server = &http.Server{ Addr: addr, Handler: s.withCORS(mux), } logger.InfoCF("server", logger.C0139, map[string]interface{}{ "addr": addr, }) // Check/log indicating it's ready for reverse proxying (per requirement) logger.InfoC("server", logger.C0140) go func() { if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.ErrorCF("server", logger.C0141, map[string]interface{}{ logger.FieldError: err.Error(), }) } }() return nil } func (s *Server) Stop(ctx context.Context) error { if s.server != nil { logger.InfoC("server", logger.C0142) return s.server.Shutdown(ctx) } return nil } func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) } func (s *Server) handleRoot(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "ClawGo Gateway Running\nTime: %s", time.Now().Format(time.RFC3339)) } func (s *Server) withCORS(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With") w.Header().Set("Access-Control-Max-Age", "86400") if r.Method == http.MethodOptions { w.WriteHeader(http.StatusNoContent) return } next.ServeHTTP(w, r) }) }