diff --git a/cmd/lingo/main.go b/cmd/lingo/main.go index 7bfec8f0..c7582a6c 100644 --- a/cmd/lingo/main.go +++ b/cmd/lingo/main.go @@ -71,11 +71,13 @@ func run() error { var metricsAddr string var probeAddr string var concurrencyPerReplica int + var requestHeaderTimeout time.Duration flag.StringVar(&metricsAddr, "metrics-bind-address", ":8082", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.IntVar(&concurrencyPerReplica, "concurrency", concurrency, "the number of simultaneous requests that can be processed by each replica") flag.IntVar(&scaleDownDelay, "scale-down-delay", scaleDownDelay, "seconds to wait before scaling down") + flag.DurationVar(&requestHeaderTimeout, "request-header-timeout", 10*time.Second, "amount of time for the client to send headers before a timeout error will occur") opts := zap.Options{ Development: true, } @@ -154,19 +156,23 @@ func run() error { proxy.MustRegister(metricsRegistry) proxyHandler := proxy.NewHandler(deploymentManager, endpointManager, queueManager) - proxyServer := &http.Server{Addr: ":8080", Handler: proxyHandler} + proxyServer := &http.Server{Addr: ":8080", Handler: proxyHandler, ReadHeaderTimeout: requestHeaderTimeout} statsHandler := &stats.Handler{ Queues: queueManager, } - statsServer := &http.Server{Addr: ":8083", Handler: statsHandler} + statsServer := &http.Server{Addr: ":8083", Handler: statsHandler, ReadHeaderTimeout: requestHeaderTimeout} var wg sync.WaitGroup wg.Add(1) go func() { defer func() { - statsServer.Shutdown(context.Background()) - proxyServer.Shutdown(context.Background()) + if err := statsServer.Shutdown(context.Background()); err != nil { + setupLog.Error(err, "shutdown stats server") + } + if err := proxyServer.Shutdown(context.Background()); err != nil { + setupLog.Error(err, "shutdown proxy server") + } wg.Done() }() if err := mgr.Start(ctx); err != nil { diff --git a/pkg/deployments/manager.go b/pkg/deployments/manager.go index a008dd70..3bea6710 100644 --- a/pkg/deployments/manager.go +++ b/pkg/deployments/manager.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "math" "net/http" "strconv" "strings" @@ -244,6 +245,9 @@ func getAnnotationInt32(ann map[string]string, key string, defaultValue int32) i log.Printf("parsing annotation as int: %v", err) return defaultValue } - - return int32(value) + if value > math.MaxInt32 { + log.Printf("invalid value that exceeds max int32: %d", value) + return defaultValue + } + return int32(value) // #nosec G109 : checked before } diff --git a/pkg/proxy/handler.go b/pkg/proxy/handler.go index a51d9d3b..3a54c94b 100644 --- a/pkg/proxy/handler.go +++ b/pkg/proxy/handler.go @@ -56,7 +56,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { modelName = "unknown" log.Printf("error reading model from request body: %v", err) w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("Bad request: unable to parse .model from JSON payload")) + _, _ = w.Write([]byte("Bad request: unable to parse .model from JSON payload")) return } log.Println("model:", modelName) @@ -65,7 +65,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !found { log.Printf("deployment not found for model: %v", err) w.WriteHeader(http.StatusNotFound) - w.Write([]byte(fmt.Sprintf("Deployment for model not found: %v", modelName))) + _, _ = w.Write([]byte(fmt.Sprintf("Deployment for model not found: %v", modelName))) return } diff --git a/pkg/stats/handler.go b/pkg/stats/handler.go index 30113ad2..8ec656d4 100644 --- a/pkg/stats/handler.go +++ b/pkg/stats/handler.go @@ -12,7 +12,7 @@ type Handler struct { Queues *queue.Manager } -func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (h *Handler) ServeHTTP(w http.ResponseWriter, _ *http.Request) { if err := json.NewEncoder(w).Encode(Stats{ ActiveRequests: h.Queues.TotalCounts(), }); err != nil {