From 7dd58bcd5a28c2711593ed4e643bbd4caf9d9035 Mon Sep 17 00:00:00 2001 From: Django Cass Date: Fri, 15 Sep 2023 07:32:14 +1000 Subject: [PATCH] Fixed an issue causing Jar decompression to fail when downloaded using chunked encoding --- remote_fetch.go | 9 ++++++++- remote_fetch_test.go | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/remote_fetch.go b/remote_fetch.go index dceae84..1aa1e84 100644 --- a/remote_fetch.go +++ b/remote_fetch.go @@ -75,7 +75,14 @@ func closeBody(resp *http.Response) func() { } func decompressResponse(bodyBytes []byte, contentLength int64, cacheLocator CacheLocator, downloadURL string) error { - zipReader, err := zip.NewReader(bytes.NewReader(bodyBytes), contentLength) + size := contentLength + // if the content length is not set (i.e. chunked encoding), + // we need to use the length of the bodyBytes otherwise + // the unzip operation will fail + if contentLength < 0 { + size = int64(len(bodyBytes)) + } + zipReader, err := zip.NewReader(bytes.NewReader(bodyBytes), size) if err != nil { return errorFetchingPostgres(err) } diff --git a/remote_fetch_test.go b/remote_fetch_test.go index c884e5c..9e6dcfb 100644 --- a/remote_fetch_test.go +++ b/remote_fetch_test.go @@ -4,6 +4,8 @@ import ( "archive/zip" "crypto/sha256" "encoding/hex" + "github.com/stretchr/testify/require" + "io" "net/http" "net/http/httptest" "os" @@ -370,3 +372,48 @@ func Test_defaultRemoteFetchStrategyWithExistingDownload(t *testing.T) { out2, err := os.ReadFile(cacheLocation) assert.Equal(t, out1, out2) } + +func Test_defaultRemoteFetchStrategy_whenContentLengthNotSet(t *testing.T) { + jarFile, cleanUp := createTempZipArchive() + defer cleanUp() + + cacheLocation := filepath.Join(filepath.Dir(jarFile), "extract_location", "cache.jar") + + bytes, err := os.ReadFile(jarFile) + if err != nil { + require.NoError(t, err) + } + contentHash := sha256.Sum256(bytes) + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasSuffix(r.RequestURI, ".sha256") { + w.WriteHeader(200) + if _, err := w.Write([]byte(hex.EncodeToString(contentHash[:]))); err != nil { + panic(err) + } + + return + } + + f, err := os.Open(jarFile) + if err != nil { + panic(err) + } + + // stream the file back so that Go uses + // chunked encoding and never sets Content-Length + _, _ = io.Copy(w, f) + })) + defer server.Close() + + remoteFetchStrategy := defaultRemoteFetchStrategy(server.URL+"/maven2", + testVersionStrategy(), + func() (s string, b bool) { + return cacheLocation, false + }) + + err = remoteFetchStrategy() + + assert.NoError(t, err) + assert.FileExists(t, cacheLocation) +}