config.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package options
  2. import (
  3. "errors"
  4. "fmt"
  5. "maps"
  6. "slices"
  7. "github.com/imgproxy/imgproxy/v3/config"
  8. "github.com/imgproxy/imgproxy/v3/ensure"
  9. "github.com/imgproxy/imgproxy/v3/imagetype"
  10. )
  11. // URLReplacement represents a URL replacement configuration
  12. type URLReplacement = config.URLReplacement
  13. // Config represents the configuration for options processing
  14. type Config struct {
  15. // Processing behavior defaults
  16. StripMetadata bool // Whether to strip metadata by default
  17. KeepCopyright bool // Whether to keep copyright information when stripping metadata
  18. StripColorProfile bool // Whether to strip color profile by default
  19. AutoRotate bool // Whether to auto-rotate images by default
  20. EnforceThumbnail bool // Whether to enforce thumbnail extraction by default
  21. ReturnAttachment bool // Whether to return images as attachments by default
  22. // Image processing formats
  23. SkipProcessingFormats []imagetype.Type // List of formats to skip processing for
  24. // Presets configuration
  25. Presets []string // Available presets
  26. OnlyPresets bool // Whether to allow only presets
  27. // Quality settings
  28. Quality int // Default quality for image processing
  29. FormatQuality map[imagetype.Type]int // Quality settings per image format
  30. // Security and validation
  31. AllowedProcessingOptions []string // List of allowed processing options
  32. // Format preference and enforcement
  33. AutoWebp bool // Whether to automatically serve WebP when supported
  34. EnforceWebp bool // Whether to enforce WebP format
  35. AutoAvif bool // Whether to automatically serve AVIF when supported
  36. EnforceAvif bool // Whether to enforce AVIF format
  37. AutoJxl bool // Whether to automatically serve JXL when supported
  38. EnforceJxl bool // Whether to enforce JXL format
  39. // Client hints
  40. EnableClientHints bool // Whether to enable client hints support
  41. // URL processing
  42. ArgumentsSeparator string // Separator for URL arguments
  43. BaseURL string // Base URL for relative URLs
  44. URLReplacements []URLReplacement // URL replacement rules
  45. Base64URLIncludesFilename bool // Whether base64 URLs include filename
  46. AllowSecurityOptions bool // Whether to allow security options in URLs
  47. }
  48. // NewDefaultConfig creates a new default configuration for options processing
  49. func NewDefaultConfig() Config {
  50. return Config{
  51. // Processing behavior defaults (copied from global config defaults)
  52. StripMetadata: true,
  53. KeepCopyright: true,
  54. StripColorProfile: true,
  55. AutoRotate: true,
  56. EnforceThumbnail: false,
  57. ReturnAttachment: false,
  58. OnlyPresets: false,
  59. // Quality settings (copied from global config defaults)
  60. Quality: 80,
  61. FormatQuality: map[imagetype.Type]int{
  62. imagetype.WEBP: 79,
  63. imagetype.AVIF: 63,
  64. imagetype.JXL: 77,
  65. },
  66. // Format preference and enforcement (copied from global config defaults)
  67. AutoWebp: false,
  68. EnforceWebp: false,
  69. AutoAvif: false,
  70. EnforceAvif: false,
  71. AutoJxl: false,
  72. EnforceJxl: false,
  73. // Client hints
  74. EnableClientHints: false,
  75. // URL processing (copied from global config defaults)
  76. ArgumentsSeparator: ":",
  77. BaseURL: "",
  78. Base64URLIncludesFilename: false,
  79. AllowSecurityOptions: false,
  80. }
  81. }
  82. // LoadConfigFromEnv loads configuration from global config variables
  83. func LoadConfigFromEnv(c *Config) (*Config, error) {
  84. c = ensure.Ensure(c, NewDefaultConfig)
  85. // Copy from global config variables
  86. c.StripMetadata = config.StripMetadata
  87. c.KeepCopyright = config.KeepCopyright
  88. c.StripColorProfile = config.StripColorProfile
  89. c.AutoRotate = config.AutoRotate
  90. c.EnforceThumbnail = config.EnforceThumbnail
  91. c.ReturnAttachment = config.ReturnAttachment
  92. // Image processing formats
  93. c.SkipProcessingFormats = slices.Clone(config.SkipProcessingFormats)
  94. // Presets configuration
  95. c.Presets = slices.Clone(config.Presets)
  96. c.OnlyPresets = config.OnlyPresets
  97. // Quality settings
  98. c.Quality = config.Quality
  99. c.FormatQuality = maps.Clone(config.FormatQuality)
  100. // Security and validation
  101. c.AllowedProcessingOptions = slices.Clone(config.AllowedProcessingOptions)
  102. // Format preference and enforcement
  103. c.AutoWebp = config.AutoWebp
  104. c.EnforceWebp = config.EnforceWebp
  105. c.AutoAvif = config.AutoAvif
  106. c.EnforceAvif = config.EnforceAvif
  107. c.AutoJxl = config.AutoJxl
  108. c.EnforceJxl = config.EnforceJxl
  109. // Client hints
  110. c.EnableClientHints = config.EnableClientHints
  111. // URL processing
  112. c.ArgumentsSeparator = config.ArgumentsSeparator
  113. c.BaseURL = config.BaseURL
  114. c.URLReplacements = slices.Clone(config.URLReplacements)
  115. c.Base64URLIncludesFilename = config.Base64URLIncludesFilename
  116. c.AllowSecurityOptions = config.AllowSecurityOptions
  117. return c, nil
  118. }
  119. // Validate validates the configuration values
  120. func (c *Config) Validate() error {
  121. // Quality validation (copied from global config validation)
  122. if c.Quality <= 0 {
  123. return fmt.Errorf("quality should be greater than 0, now - %d", c.Quality)
  124. } else if c.Quality > 100 {
  125. return fmt.Errorf("quality can't be greater than 100, now - %d", c.Quality)
  126. }
  127. // Format quality validation
  128. for format, quality := range c.FormatQuality {
  129. if quality <= 0 {
  130. return fmt.Errorf("format quality for %s should be greater than 0, now - %d", format, quality)
  131. } else if quality > 100 {
  132. return fmt.Errorf("format quality for %s can't be greater than 100, now - %d", format, quality)
  133. }
  134. }
  135. // Arguments separator validation
  136. if c.ArgumentsSeparator == "" {
  137. return errors.New("arguments separator cannot be empty")
  138. }
  139. return nil
  140. }