From 1065add75e7dba8e517ec75bab68bef67ca9c1c0 Mon Sep 17 00:00:00 2001 From: Ryan Phillips Date: Thu, 12 Sep 2019 15:18:49 -0500 Subject: [PATCH] fix kubelet status http calls with truncation PR#76518 introduced a change to limit the the read on various calls with utilio.ReadAtMost. By design, ReadAtMost will return an error if there is a truncation, but the calling code needs to know to handle it. --- pkg/probe/http/http.go | 6 +++- pkg/probe/http/http_test.go | 68 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/pkg/probe/http/http.go b/pkg/probe/http/http.go index 8dc8bb46bbd..0617b829614 100644 --- a/pkg/probe/http/http.go +++ b/pkg/probe/http/http.go @@ -113,7 +113,11 @@ func DoHTTPProbe(url *url.URL, headers http.Header, client GetHTTPInterface) (pr defer res.Body.Close() b, err := utilio.ReadAtMost(res.Body, maxRespBodyLength) if err != nil { - return probe.Failure, "", err + if err == utilio.ErrLimitReached { + klog.V(4).Infof("Non fatal body truncation for %s, Response: %v", url.String(), *res) + } else { + return probe.Failure, "", err + } } body := string(b) if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { diff --git a/pkg/probe/http/http_test.go b/pkg/probe/http/http_test.go index aa8712f0e73..39f6f2dadcd 100644 --- a/pkg/probe/http/http_test.go +++ b/pkg/probe/http/http_test.go @@ -17,6 +17,7 @@ limitations under the License. package http import ( + "bytes" "fmt" "net" "net/http" @@ -368,3 +369,70 @@ func TestHTTPProbeChecker_HostHeaderPreservedAfterRedirect(t *testing.T) { }) } } + +func TestHTTPProbeChecker_PayloadTruncated(t *testing.T) { + successHostHeader := "www.success.com" + oversizePayload := bytes.Repeat([]byte("a"), maxRespBodyLength+1) + truncatedPayload := bytes.Repeat([]byte("a"), maxRespBodyLength) + + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/success": + if r.Host == successHostHeader { + w.WriteHeader(http.StatusOK) + w.Write(oversizePayload) + } else { + http.Error(w, "", http.StatusBadRequest) + } + default: + http.Error(w, "", http.StatusInternalServerError) + } + }) + server := httptest.NewServer(handler) + defer server.Close() + + headers := http.Header{} + headers.Add("Host", successHostHeader) + t.Run("truncated payload", func(t *testing.T) { + prober := New(false) + target, err := url.Parse(server.URL + "/success") + require.NoError(t, err) + result, body, err := prober.Probe(target, headers, wait.ForeverTestTimeout) + assert.NoError(t, err) + assert.Equal(t, result, probe.Success) + assert.Equal(t, body, string(truncatedPayload)) + }) +} + +func TestHTTPProbeChecker_PayloadNormal(t *testing.T) { + successHostHeader := "www.success.com" + normalPayload := bytes.Repeat([]byte("a"), maxRespBodyLength-1) + + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/success": + if r.Host == successHostHeader { + w.WriteHeader(http.StatusOK) + w.Write(normalPayload) + } else { + http.Error(w, "", http.StatusBadRequest) + } + default: + http.Error(w, "", http.StatusInternalServerError) + } + }) + server := httptest.NewServer(handler) + defer server.Close() + + headers := http.Header{} + headers.Add("Host", successHostHeader) + t.Run("normal payload", func(t *testing.T) { + prober := New(false) + target, err := url.Parse(server.URL + "/success") + require.NoError(t, err) + result, body, err := prober.Probe(target, headers, wait.ForeverTestTimeout) + assert.NoError(t, err) + assert.Equal(t, result, probe.Success) + assert.Equal(t, body, string(normalPayload)) + }) +}