diff --git a/services/webdav/pkg/thumbnail/workflow/workflow.go b/services/webdav/pkg/thumbnail/workflow/workflow.go index 2d781ff96d..029259ae49 100644 --- a/services/webdav/pkg/thumbnail/workflow/workflow.go +++ b/services/webdav/pkg/thumbnail/workflow/workflow.go @@ -129,9 +129,11 @@ func fileIsProcessing(info *providerv1beta1.ResourceInfo) bool { // // The checksum is hashed rather than used as it comes: it is not this service's // to trust, an OCM share takes it from a remote PROPFIND, and it ends up as a -// path on disk and as an object key. -func thumbnailStorageKey(checksum string, w, h int, format, operation string) string { - sum := sha256.Sum256([]byte(checksum)) +// path on disk and as an object key. The source type is hashed with it, because +// the same bytes under two types are not the same thumbnail: the type picks the +// extractor, and what it finds depends on it. +func thumbnailStorageKey(checksum, mimeType string, w, h int, format, operation string) string { + sum := sha256.Sum256([]byte(checksum + "\x00" + mimeType)) hash := hex.EncodeToString(sum[:]) return hash[:2] + "/" + hash[2:4] + "/" + hash[4:] + "/" + fmt.Sprintf("%dx%d-%s.%s", w, h, operation, format) @@ -453,7 +455,7 @@ func (w *ThumbnailWorkflow) generate(ctx context.Context, ref *providerv1beta1.R // requests that produce the same image share one entry and the number of // entries per file stays bounded by the ladder. It needs nothing but the // request, so a hit still returns without touching storage. - cacheKey := thumbnailStorageKey(checksum, box.Dx(), box.Dy(), outputFormat, operation) + cacheKey := thumbnailStorageKey(checksum, mimeType, box.Dx(), box.Dy(), outputFormat, operation) if w.cache != nil { cached, err := w.cache.Get(cacheKey) diff --git a/services/webdav/pkg/thumbnail/workflow/workflow_test.go b/services/webdav/pkg/thumbnail/workflow/workflow_test.go index 389d95f232..1c6d7cbd4e 100644 --- a/services/webdav/pkg/thumbnail/workflow/workflow_test.go +++ b/services/webdav/pkg/thumbnail/workflow/workflow_test.go @@ -421,7 +421,7 @@ var _ = Describe("ThumbnailWorkflow", func() { Expect(data).To(Equal(thumbBytes)) Expect(contentType).To(Equal("image/jpeg")) - cached, err := testCache.Get(thumbnailStorageKey("cb56752477cae6405f85b131872c60d21b967c6a", 128, 128, "jpg", "fill")) + cached, err := testCache.Get(thumbnailStorageKey("cb56752477cae6405f85b131872c60d21b967c6a", "image/jpeg", 128, 128, "jpg", "fill")) Expect(err).ToNot(HaveOccurred()) Expect(cached).To(Equal(thumbBytes)) }) @@ -936,13 +936,13 @@ var _ = Describe("ThumbnailWorkflow", func() { }, Entry("a png keeps its alpha channel", "image/png", "img.png", "smart/filters:format(png)", "image/png", - thumbnailStorageKey("1f0c9f1b6e4b4b2a9c1d7f3e8a5b6c7d8e9f0a1b", 64, 64, "png", "fill")), + thumbnailStorageKey("1f0c9f1b6e4b4b2a9c1d7f3e8a5b6c7d8e9f0a1b", "image/png", 64, 64, "png", "fill")), Entry("a gif keeps its animation", "image/gif", "anim.gif", "filters:format(gif)", "image/gif", - thumbnailStorageKey("1f0c9f1b6e4b4b2a9c1d7f3e8a5b6c7d8e9f0a1b", 64, 64, "gif", "stretch")), + thumbnailStorageKey("1f0c9f1b6e4b4b2a9c1d7f3e8a5b6c7d8e9f0a1b", "image/gif", 64, 64, "gif", "stretch")), Entry("a bmp becomes a jpeg", "image/bmp", "scan.bmp", "smart/filters:format(jpg)", "image/jpeg", - thumbnailStorageKey("1f0c9f1b6e4b4b2a9c1d7f3e8a5b6c7d8e9f0a1b", 64, 64, "jpg", "fill")), + thumbnailStorageKey("1f0c9f1b6e4b4b2a9c1d7f3e8a5b6c7d8e9f0a1b", "image/bmp", 64, 64, "jpg", "fill")), ) It("follows a configured chain into a format the built-in generator cannot write", func() { @@ -986,7 +986,7 @@ var _ = Describe("ThumbnailWorkflow", func() { Describe("cache hit shortcut", func() { It("should return cached thumbnail without calling generator or downloading the file", func() { cachedThumb := []byte("cached-thumbnail") - err := testCache.Put(thumbnailStorageKey("cb56752477cae6405f85b131872c60d21b967c6a", 128, 128, "jpg", "fill"), cachedThumb) + err := testCache.Put(thumbnailStorageKey("cb56752477cae6405f85b131872c60d21b967c6a", "image/jpeg", 128, 128, "jpg", "fill"), cachedThumb) Expect(err).ToNot(HaveOccurred()) // No download expectations are set up. If the workflow tried to @@ -1266,7 +1266,7 @@ var _ = Describe("ThumbnailWorkflow", func() { Expect(data).To(Equal(thumbBytes)) Expect(contentType).To(Equal("image/jpeg")) - cached, err := testCache.Get(thumbnailStorageKey("5ba1b086d95a7e0fd8ff4323caee0c412ab07fc3", 64, 64, "jpg", "fill")) + cached, err := testCache.Get(thumbnailStorageKey("5ba1b086d95a7e0fd8ff4323caee0c412ab07fc3", "image/jpeg", 64, 64, "jpg", "fill")) Expect(err).ToNot(HaveOccurred()) Expect(cached).To(Equal(thumbBytes)) })