Files
canada-kaktus/internal/health.go
Julian Haseleu 00708eef30
Some checks failed
PR Build / Test (pull_request) Failing after 2m42s
PR Build / Build_Image (pull_request) Successful in 1m24s
fix security - health endpoint will now properly handle timeouts
2025-10-09 14:36:27 +00:00

67 lines
1.3 KiB
Go

package internal
import (
"fmt"
"net/http"
"sync"
"time"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
)
type HealthServer struct {
mu sync.RWMutex
state int
}
func NewHealthServer() *HealthServer {
return &HealthServer{
state: http.StatusOK,
}
}
func (hs *HealthServer) SetHealthState(code int) {
hs.mu.Lock()
defer hs.mu.Unlock()
hs.state = code
}
func (hs *HealthServer) GetHealthState() int {
hs.mu.RLock()
defer hs.mu.RUnlock()
return hs.state
}
func (hs *HealthServer) Start() {
r := mux.NewRouter()
r.Use(mux.CORSMethodMiddleware(r))
r.HandleFunc("/health", hs.sendHealth).Methods(http.MethodGet)
server := &http.Server{
Addr: "0.0.0.0:8080",
Handler: r,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
err := server.ListenAndServe()
if err != nil {
log.WithFields(log.Fields{
"Caller": "HealthServer.Start",
}).Error(fmt.Sprintf("Error creating health endpoint: %s", err.Error()))
}
}
func (hs *HealthServer) sendHealth(w http.ResponseWriter, r *http.Request) {
code := hs.GetHealthState()
w.WriteHeader(code)
_, err := w.Write([]byte{})
if err != nil {
log.WithFields(log.Fields{
"Caller": "HealthServer.sendHealth",
}).Error(fmt.Sprintf("Error answering health endpoint: %s", err.Error()))
}
}