diff --git a/app/cmd/goaws.go b/app/cmd/goaws.go index a0f4546..1f7a8f2 100644 --- a/app/cmd/goaws.go +++ b/app/cmd/goaws.go @@ -140,13 +140,21 @@ func main() { // Metrics: gauge updater — пересчёт очередей/сообщений per tenant каждые 15 секунд metrics.StartGaugeUpdater(15*time.Second, quit) - // HTTP сервер с таймаутами + // HTTP сервер с таймаутами (рекомендации ревью Соннета, план v0.1.35): + // - ReadHeaderTimeout 10с — лимит ТОЛЬКО на чтение заголовков (slowloris). + // ReadTimeout НЕ ставим: он обрывал бы запросы с медленной/большой + // загрузкой тела (в т.ч. большие SendMessage) и ломал бы long-poll. + // - WriteTimeout 35с — ответ; чуть больше max WaitTimeSeconds (20с long-poll). + // - IdleTimeout 90с — keep-alive; больше интервала ретраев клиентских SDK. + // - MaxHeaderBytes 8192 — защита от гигантских заголовков + // (платформа режет >16KB, наш лимит строже). srv := &http.Server{ - Addr: "0.0.0.0:" + port, - Handler: r, - ReadTimeout: 30 * time.Second, - WriteTimeout: 35 * time.Second, // чуть больше чем max WaitTimeSeconds (20s) - IdleTimeout: 60 * time.Second, + Addr: "0.0.0.0:" + port, + Handler: r, + ReadHeaderTimeout: 10 * time.Second, + WriteTimeout: 35 * time.Second, + IdleTimeout: 90 * time.Second, + MaxHeaderBytes: 8192, } // Запуск в горутине для graceful shutdown