package main import ( "context" "errors" "log" "net/http" "time" ) // serveHTTP runs the panel's HTTP server until ctx is cancelled. Phase 1 serves // only a placeholder page and a health check; the login flow and real UI arrive // in Phase 2. func serveHTTP(ctx context.Context, addr string) error { mux := http.NewServeMux() mux.HandleFunc("/healthz", handleHealth) mux.HandleFunc("/", handleIndex) srv := &http.Server{ Addr: addr, Handler: mux, ReadHeaderTimeout: 10 * time.Second, } // Shut the server down cleanly when the process is asked to stop. go func() { <-ctx.Done() shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() _ = srv.Shutdown(shutdownCtx) }() log.Printf("http panel listening on %s", addr) if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { return err } return nil } func handleHealth(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("ok\n")) } func handleIndex(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") _, _ = w.Write([]byte(indexHTML)) } const indexHTML = ` SelfPost

SelfPost

The control panel is starting up. Administrator setup and login arrive in a later build.

`