From 5ea75dcc6758c1a3a767fc674463b30cf06796c5 Mon Sep 17 00:00:00 2001 From: 7y-9 Date: Tue, 2 Jun 2026 03:21:19 +0800 Subject: [PATCH] fix(http): handle invalid gzip stream errors (#9767) * fix(http): handle invalid gzip stream errors Explain: - problem: ReadUrlAsStream could panic when a response claimed gzip encoding but the body was not a valid gzip stream. - root cause: the gzip reader error was ignored and a nil reader was deferred and read from. - fix: return the gzip.NewReader error before registering Close or reading. - validation: go test ./weed/util/http -run TestReadUrlAsStreamReturnsGzipReaderError -count=1; git diff --check. * test: avoid closing shared global HTTP client in unit test --- weed/util/http/http_global_client_util.go | 3 +++ .../util/http/http_global_client_util_test.go | 23 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/weed/util/http/http_global_client_util.go b/weed/util/http/http_global_client_util.go index 24e38f8c7..1a78bd412 100644 --- a/weed/util/http/http_global_client_util.go +++ b/weed/util/http/http_global_client_util.go @@ -397,6 +397,9 @@ func ReadUrlAsStream(ctx context.Context, fileUrl, jwt string, cipherKey []byte, switch contentEncoding { case "gzip": reader, err = gzip.NewReader(r.Body) + if err != nil { + return true, err + } defer reader.Close() default: reader = r.Body diff --git a/weed/util/http/http_global_client_util_test.go b/weed/util/http/http_global_client_util_test.go index f24bd5aca..cc17301e3 100644 --- a/weed/util/http/http_global_client_util_test.go +++ b/weed/util/http/http_global_client_util_test.go @@ -1,6 +1,11 @@ package http -import "testing" +import ( + "context" + "net/http" + "net/http/httptest" + "testing" +) func TestAppendQueryParameter(t *testing.T) { testCases := []struct { @@ -70,3 +75,19 @@ func TestAppendQueryParameter(t *testing.T) { }) } } + +func TestReadUrlAsStreamReturnsGzipReaderError(t *testing.T) { + InitGlobalHttpClient() + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Encoding", "gzip") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte("not gzip")) + })) + defer server.Close() + + _, err := ReadUrlAsStream(context.Background(), server.URL, "", nil, false, true, 0, 0, func(data []byte) {}) + if err == nil { + t.Fatal("ReadUrlAsStream returned nil error for invalid gzip response") + } +}