diff --git a/services/webdav/README.md b/services/webdav/README.md index a50d5368ca..22ac474844 100644 --- a/services/webdav/README.md +++ b/services/webdav/README.md @@ -76,7 +76,7 @@ Three settings say what is made of what. They are merged onto the built-in defau | `OC_THUMBNAIL_TYPE_MAPPING` | The type a thumbnail is returned in, per source type, as `mime:mime` entries, e.g. `image/vnd.microsoft.icon:image/png` | | `OC_THUMBNAIL_GENERATOR_FORMATS` | The formats the generator writes, as `mime:format` entries, e.g. `image/webp:webp`. The format is the name its own `format(...)` filter uses | -Reading them as a chain: a source type is mapped to the type its thumbnail is returned in, and that type is asked for by the name the generator knows it under. An icon becomes `image/png`, which the generator is asked for as `format(png)`. A type nobody mapped becomes a JPEG, and a mapping onto a type the generator has no format name for is refused at startup, as long as previews are enabled. +Reading them as a chain: a source type is mapped to the type its thumbnail is returned in, and that type is asked for by the name the generator knows it under. An icon becomes `image/png`, which the generator is asked for as `format(png)`. A type nobody mapped becomes a JPEG, and so does a mapping onto a type this service has no format name for: what a generator behind the URL really writes is its own business, and a wrong guess here must not keep the service from starting. The defaults return `image/png` for png and icon sources, keep `image/gif` for a gif and return `image/jpeg` for everything else, so a client must read the response's `Content-Type` instead of assuming the type it got before. diff --git a/services/webdav/pkg/config/config.go b/services/webdav/pkg/config/config.go index fa5c3458df..9b7b6d09e3 100644 --- a/services/webdav/pkg/config/config.go +++ b/services/webdav/pkg/config/config.go @@ -43,8 +43,8 @@ type Config struct { ThumbnailCacheS3SecretKey string `yaml:"thumbnail_cache_s3_secret_key" env:"WEBDAV_THUMBNAIL_CACHE_S3_SECRET_KEY" desc:"S3 secret key for thumbnail cache authentication." introductionVersion:"%%NEXT%%"` ThumbnailSourceTypes []string `yaml:"thumbnail_source_types" env:"OC_THUMBNAIL_SOURCE_TYPES;WEBDAV_THUMBNAIL_SOURCE_TYPES" desc:"Additional mime types a preview is announced and attempted for, e.g. image/vnd.microsoft.icon for a generator that reads icons. The built-in list is included; this only adds to them. A type the running generator cannot read answers 404." introductionVersion:"%%NEXT%%"` - ThumbnailGeneratorFormats []string `yaml:"thumbnail_generator_formats" env:"OC_THUMBNAIL_GENERATOR_FORMATS;WEBDAV_THUMBNAIL_GENERATOR_FORMATS" desc:"The formats the thumbnail generator writes, as mime:format entries, e.g. image/webp:webp. The format is the name the generator's own format filter uses. A type that is not listed is one the generator cannot write, so a mapping onto it is refused at startup." introductionVersion:"%%NEXT%%"` - ThumbnailTypeMapping []string `yaml:"thumbnail_type_mapping" env:"OC_THUMBNAIL_TYPE_MAPPING;WEBDAV_THUMBNAIL_TYPE_MAPPING" desc:"The type a thumbnail is returned in, per type of the image it is made from, as mime:mime entries, e.g. image/vnd.microsoft.icon:image/png. The target is asked for by the name WEBDAV_THUMBNAIL_GENERATOR_FORMATS gives it. A type that is not listed becomes a JPEG; a target the generator cannot write is refused at startup." introductionVersion:"%%NEXT%%"` + ThumbnailGeneratorFormats []string `yaml:"thumbnail_generator_formats" env:"OC_THUMBNAIL_GENERATOR_FORMATS;WEBDAV_THUMBNAIL_GENERATOR_FORMATS" desc:"The formats the thumbnail generator writes, as mime:format entries, e.g. image/webp:webp. The format is the name the generator's own format filter uses. A type that is not listed is asked for as a JPEG instead, because what the generator behind the URL really writes is its own business." introductionVersion:"%%NEXT%%"` + ThumbnailTypeMapping []string `yaml:"thumbnail_type_mapping" env:"OC_THUMBNAIL_TYPE_MAPPING;WEBDAV_THUMBNAIL_TYPE_MAPPING" desc:"The type a thumbnail is returned in, per type of the image it is made from, as mime:mime entries, e.g. image/vnd.microsoft.icon:image/png. The target is asked for by the name WEBDAV_THUMBNAIL_GENERATOR_FORMATS gives it. A type that is not listed becomes a JPEG; a target this service has no format name for is asked for as a JPEG as well." introductionVersion:"%%NEXT%%"` // the yaml key stays unprefixed, a config file written against it has to keep working ThumbnailFontMapFile string `yaml:"font_map_file" env:"THUMBNAILS_TXT_FONTMAP_FILE;WEBDAV_THUMBNAIL_TXT_FONTMAP_FILE" desc:"The path to a font map file for txt thumbnails." introductionVersion:"%%NEXT%%"` diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go index 503140b8a2..a992753a5f 100644 --- a/services/webdav/pkg/service/v0/service.go +++ b/services/webdav/pkg/service/v0/service.go @@ -9,7 +9,6 @@ import ( "net/http" "net/url" "path" - "sort" "strconv" "strings" "time" @@ -183,9 +182,6 @@ func newThumbnailWorkflow(conf *config.Config, sourceTypes thumbnail.SourceTypes typeMapping := thumbnail.NewTypeMapping(conf.ThumbnailTypeMapping) formats := generator.NewFormats(conf.ThumbnailGeneratorFormats) - if err := checkTypeMapping(typeMapping, formats); err != nil { - return nil, err - } s3cfg := cache.BuildS3CacheConfig( conf.ThumbnailCacheS3Bucket, @@ -228,24 +224,6 @@ func newThumbnailWorkflow(conf *config.Config, sourceTypes thumbnail.SourceTypes ) } -// checkTypeMapping refuses a mapping that asks for a type the generator has no -// format name for: the thumbnail would silently become a JPEG instead. -func checkTypeMapping(mapping thumbnail.TypeMapping, formats generator.Formats) error { - var unknown []string - for source, target := range mapping.Targets() { - if target == "" || formats.For(target) != "" { - continue - } - unknown = append(unknown, fmt.Sprintf("%s (mapped from %s)", target, source)) - } - if len(unknown) == 0 { - return nil - } - sort.Strings(unknown) - - return fmt.Errorf("thumbnail type mapping: no generator format for %s", strings.Join(unknown, ", ")) -} - // Webdav implements the business logic for Service. type Webdav struct { sourceTypes thumbnail.SourceTypes diff --git a/services/webdav/pkg/service/v0/typemapping_test.go b/services/webdav/pkg/service/v0/typemapping_test.go deleted file mode 100644 index c9024d95c8..0000000000 --- a/services/webdav/pkg/service/v0/typemapping_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package svc - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/opencloud-eu/opencloud/services/webdav/pkg/generator" - "github.com/opencloud-eu/opencloud/services/webdav/pkg/thumbnail" -) - -var _ = Describe("checkTypeMapping", func() { - It("accepts the defaults", func() { - Expect(checkTypeMapping(thumbnail.NewTypeMapping(nil), generator.NewFormats(nil))).To(Succeed()) - }) - - It("accepts a pair that was configured together", func() { - Expect(checkTypeMapping( - thumbnail.NewTypeMapping([]string{"image/png:image/webp"}), - generator.NewFormats([]string{"image/webp:webp"}), - )).To(Succeed()) - }) - - It("refuses a target the generator has no format for", func() { - err := checkTypeMapping( - thumbnail.NewTypeMapping([]string{"image/png:image/webp"}), - generator.NewFormats(nil), - ) - - Expect(err).To(MatchError(ContainSubstring("no generator format for image/webp (mapped from image/png)"))) - }) - - It("names every bad entry", func() { - err := checkTypeMapping( - thumbnail.NewTypeMapping([]string{"image/png:image/avif", "image/gif:image/webp"}), - generator.NewFormats(nil), - ) - - Expect(err).To(MatchError(ContainSubstring("image/avif (mapped from image/png)"))) - Expect(err).To(MatchError(ContainSubstring("image/webp (mapped from image/gif)"))) - }) - - It("takes an empty target as no override", func() { - Expect(checkTypeMapping( - thumbnail.NewTypeMapping([]string{"image/png:"}), - generator.NewFormats(nil), - )).To(Succeed()) - }) -})