From a4ac720ebaed13776346f8d91d79d4762d7af321 Mon Sep 17 00:00:00 2001 From: "polylane[bot]" <277585245+polylane[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 15:29:05 +0200 Subject: [PATCH] fix(checker): raise probe response body cap to 10 MiB (#2727) * fix(checker): cap probe response body read to prevent OOM-kill waves Co-authored-by: polylane[bot] <277585245+polylane[bot]@users.noreply.github.com> * fix(checker): raise probe response body cap to 10 MiB Co-authored-by: polylane[bot] <277585245+polylane[bot]@users.noreply.github.com> Co-authored-by: polylane[bot] <277585245+polylane[bot]@users.noreply.github.com> --------- Co-authored-by: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Co-authored-by: polylane[bot] <277585245+polylane[bot]@users.noreply.github.com> --- apps/checker/checker/http.go | 8 +++++++- apps/checker/checker/http_test.go | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/checker/checker/http.go b/apps/checker/checker/http.go index f85f0a0f..aef56126 100644 --- a/apps/checker/checker/http.go +++ b/apps/checker/checker/http.go @@ -43,6 +43,10 @@ type Response struct { Timing Timing `json:"timing"` } +// maxResponseBodyBytes caps the read of a probed response body so a large body +// cannot OOM the 512 MB checker machines (exit 137 waves). +const maxResponseBodyBytes = 10 << 20 // 10 MiB + // decodeBase64Body decodes a data URL base64 body if needed func decodeBase64Body(body string) ([]byte, error) { data := strings.Split(body, ",") @@ -145,7 +149,9 @@ func Http(ctx context.Context, client *http.Client, inputData request.HttpChecke defer response.Body.Close() - body, err := io.ReadAll(response.Body) + // Cap the response body: an endpoint returning a large body would + // otherwise OOM these 512 MB machines (fleet-wide exit 137 waves). + body, err := io.ReadAll(io.LimitReader(response.Body, maxResponseBodyBytes)) timing.TransferDone = time.Now().UTC().UnixMilli() diff --git a/apps/checker/checker/http_test.go b/apps/checker/checker/http_test.go index 070717a9..b09c89fc 100644 --- a/apps/checker/checker/http_test.go +++ b/apps/checker/checker/http_test.go @@ -28,6 +28,24 @@ func NewTestClient(fn RoundTripFunc) *http.Client { } } +func Test_HttpCapsResponseBody(t *testing.T) { + client := NewTestClient(func(req *http.Request) *http.Response { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewReader(bytes.Repeat([]byte("b"), 20<<20))), + Header: make(http.Header), + } + }) + + got, err := checker.Http(context.Background(), client, request.HttpCheckerRequest{URL: "https://openstat.us", CronTimestamp: 1}) + if err != nil { + t.Fatalf("Http() error = %v", err) + } + if got.Body != string(bytes.Repeat([]byte("b"), 10<<20)) { + t.Errorf("Http() body length = %d, want %d (capped by maxResponseBodyBytes)", len(got.Body), 10<<20) + } +} + func Test_ping(t *testing.T) { type args struct { -- 2.51.2