diff --git a/dependency_cache.go b/dependency_cache.go index 7453ad5..03f94fb 100644 --- a/dependency_cache.go +++ b/dependency_cache.go @@ -167,7 +167,9 @@ func (d *DependencyCache) Artifact(dependency BuildpackDependency, mods ...Reque actual BuildpackDependency artifact string file string + hasher = sha256.New() uri = dependency.URI + uriSha string ) for d, u := range d.Mappings { @@ -177,12 +179,18 @@ func (d *DependencyCache) Artifact(dependency BuildpackDependency, mods ...Reque } } + // downloaded artifact will have the uri sha as its filename + hasher.Write([]byte(uri)) + uriSha = hex.EncodeToString(hasher.Sum(nil)) + if dependency.SHA256 == "" { d.Logger.Headerf("%s Dependency has no SHA256. Skipping cache.", color.New(color.FgYellow, color.Bold).Sprint("Warning:")) d.Logger.Bodyf("%s from %s", color.YellowString("Downloading"), uri) - artifact = filepath.Join(d.DownloadPath, filepath.Base(uri)) + + artifact = filepath.Join(d.DownloadPath, uriSha) + if err := d.download(uri, artifact, mods...); err != nil { return nil, fmt.Errorf("unable to download %s\n%w", uri, err) } @@ -219,7 +227,7 @@ func (d *DependencyCache) Artifact(dependency BuildpackDependency, mods ...Reque } d.Logger.Bodyf("%s from %s", color.YellowString("Downloading"), uri) - artifact = filepath.Join(d.DownloadPath, dependency.SHA256, filepath.Base(uri)) + artifact = filepath.Join(d.DownloadPath, dependency.SHA256, uriSha) if err := d.download(uri, artifact, mods...); err != nil { return nil, fmt.Errorf("unable to download %s\n%w", uri, err) } diff --git a/dependency_cache_test.go b/dependency_cache_test.go index e9e99c9..c1c6ae7 100644 --- a/dependency_cache_test.go +++ b/dependency_cache_test.go @@ -17,7 +17,10 @@ package libpak_test import ( + "crypto/sha256" + "encoding/hex" "fmt" + "hash" "io" "net/http" "os" @@ -155,6 +158,7 @@ func testDependencyCache(t *testing.T, context spec.G, it spec.S) { downloadPath string dependency libpak.BuildpackDependency dependencyCache libpak.DependencyCache + hasher hash.Hash server *ghttp.Server ) @@ -164,6 +168,8 @@ func testDependencyCache(t *testing.T, context spec.G, it spec.S) { cachePath = t.TempDir() Expect(err).NotTo(HaveOccurred()) + hasher = sha256.New() + downloadPath = t.TempDir() Expect(err).NotTo(HaveOccurred()) @@ -317,6 +323,32 @@ func testDependencyCache(t *testing.T, context spec.G, it spec.S) { Expect(io.ReadAll(a)).To(Equal([]byte("alternate-fixture"))) }) + it("sets downloaded file name to uri's sha256", func() { + server.AppendHandlers(ghttp.RespondWith(http.StatusOK, "test-fixture")) + + hasher.Write([]byte(dependency.URI)) + + a, err := dependencyCache.Artifact(dependency) + Expect(err).NotTo(HaveOccurred()) + + Expect(io.ReadAll(a)).To(Equal([]byte("test-fixture"))) + Expect(filepath.Base(a.Name())).To(Equal(hex.EncodeToString(hasher.Sum(nil)))) + }) + + it("sets downloaded file name to uri's sha256 with empty SHA256 and query parameters in the uri", func() { + dependency.SHA256 = "" + dependency.URI = fmt.Sprintf("%s/test-path?param1=value1¶m2=value2", server.URL()) + server.AppendHandlers(ghttp.RespondWith(http.StatusOK, "alternate-fixture")) + + hasher.Write([]byte(dependency.URI)) + + a, err := dependencyCache.Artifact(dependency) + Expect(err).NotTo(HaveOccurred()) + + Expect(io.ReadAll(a)).To(Equal([]byte("alternate-fixture"))) + Expect(filepath.Base(a.Name())).To(Equal(hex.EncodeToString(hasher.Sum(nil)))) + }) + it("sets User-Agent", func() { server.AppendHandlers(ghttp.CombineHandlers( ghttp.VerifyHeaderKV("User-Agent", "test-user-agent"),