Files
podinfo/pkg/api/http/chunked.go
T
Stefan Prodan 302c092cce Fix panic on GET /chunked from integer overflow
HttpServerTimeout is a time.Duration (nanoseconds); the default-delay
branch scaled it by time.Second again, overflowing int64 to a negative
value and passing it to rand.Intn, which panics. The bare /chunked route
(no wait param) hit this on every request.

Convert the timeout to whole seconds in a guarded helper that keeps
rand.Intn's argument positive, and add a regression test.
2026-06-08 23:58:36 +03:00

61 lines
1.6 KiB
Go

package http
import (
"math/rand"
"net/http"
"strconv"
"time"
"github.com/gorilla/mux"
)
// Chunked godoc
// @Summary Chunked transfer encoding
// @Description uses transfer-encoding type chunked to give a partial response and then waits for the specified period
// @Tags HTTP API
// @Accept json
// @Produce json
// @Param seconds path int true "seconds to wait for"
// @Router /chunked/{seconds} [get]
// @Success 200 {object} http.MapResponse
func (s *Server) chunkedHandler(w http.ResponseWriter, r *http.Request) {
_, span := s.tracer.Start(r.Context(), "chunkedHandler")
defer span.End()
vars := mux.Vars(r)
delay, err := strconv.Atoi(vars["wait"])
if err != nil {
delay = randomDelaySeconds(s.config.HttpServerTimeout)
}
flusher, ok := w.(http.Flusher)
if !ok {
s.ErrorResponse(w, r, span, "Streaming unsupported!", http.StatusInternalServerError)
return
}
w.Header().Set("Connection", "Keep-Alive")
w.Header().Set("Transfer-Encoding", "chunked")
w.Header().Set("X-Content-Type-Options", "nosniff")
flusher.Flush()
time.Sleep(time.Duration(delay) * time.Second)
s.JSONResponse(w, r, map[string]int{"delay": delay})
flusher.Flush()
}
// randomDelaySeconds returns a random delay in seconds within [10, timeout),
// used when no explicit wait is provided. timeout is a time.Duration, so it is
// converted to whole seconds; the upper bound is clamped to keep rand.Intn's
// argument positive (it panics on a non-positive argument).
func randomDelaySeconds(timeout time.Duration) int {
maxDelay := int(timeout / time.Second)
if maxDelay <= 11 {
maxDelay = 12
}
return rand.Intn(maxDelay-10) + 10
}