package api import ( "context" "crypto/tls" "crypto/x509" "fmt" "net/http" "os" "time" ) // Server represents the API server for KAT type Server struct { httpServer *http.Server router *Router certFile string keyFile string caFile string } // NewServer creates a new API server instance func NewServer(addr string, certFile, keyFile, caFile string) (*Server, error) { router := NewRouter() server := &Server{ router: router, certFile: certFile, keyFile: keyFile, caFile: caFile, } // Create the HTTP server with TLS config server.httpServer = &http.Server{ Addr: addr, Handler: router, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 120 * time.Second, } return server, nil } // Start begins listening for requests func (s *Server) Start() error { // Load server certificate and key cert, err := tls.LoadX509KeyPair(s.certFile, s.keyFile) if err != nil { return fmt.Errorf("failed to load server certificate and key: %w", err) } // Load CA certificate for client verification caCert, err := os.ReadFile(s.caFile) if err != nil { return fmt.Errorf("failed to read CA certificate: %w", err) } caCertPool := x509.NewCertPool() if !caCertPool.AppendCertsFromPEM(caCert) { return fmt.Errorf("failed to append CA certificate to pool") } // Configure TLS s.httpServer.TLSConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: caCertPool, MinVersion: tls.VersionTLS12, } // Start the server return s.httpServer.ListenAndServeTLS("", "") } // Stop gracefully shuts down the server func (s *Server) Stop(ctx context.Context) error { return s.httpServer.Shutdown(ctx) } // RegisterJoinHandler registers the handler for agent join requests func (s *Server) RegisterJoinHandler(handler http.HandlerFunc) { s.router.HandleFunc("POST", "/internal/v1alpha1/join", handler) }