config.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. package config
  2. import (
  3. "flag"
  4. "fmt"
  5. "math"
  6. "os"
  7. "regexp"
  8. "runtime"
  9. log "github.com/sirupsen/logrus"
  10. "github.com/imgproxy/imgproxy/v3/config/configurators"
  11. "github.com/imgproxy/imgproxy/v3/imagetype"
  12. "github.com/imgproxy/imgproxy/v3/version"
  13. )
  14. var (
  15. Network string
  16. Bind string
  17. ReadTimeout int
  18. WriteTimeout int
  19. KeepAliveTimeout int
  20. DownloadTimeout int
  21. Concurrency int
  22. RequestsQueueSize int
  23. MaxClients int
  24. TTL int
  25. CacheControlPassthrough bool
  26. SetCanonicalHeader bool
  27. SoReuseport bool
  28. PathPrefix string
  29. MaxSrcResolution int
  30. MaxSrcFileSize int
  31. MaxAnimationFrames int
  32. MaxSvgCheckBytes int
  33. MaxRedirects int
  34. JpegProgressive bool
  35. PngInterlaced bool
  36. PngQuantize bool
  37. PngQuantizationColors int
  38. AvifSpeed int
  39. Quality int
  40. FormatQuality map[imagetype.Type]int
  41. StripMetadata bool
  42. KeepCopyright bool
  43. StripColorProfile bool
  44. AutoRotate bool
  45. EnforceThumbnail bool
  46. ReturnAttachment bool
  47. EnableWebpDetection bool
  48. EnforceWebp bool
  49. EnableAvifDetection bool
  50. EnforceAvif bool
  51. EnableClientHints bool
  52. PreferredFormats []imagetype.Type
  53. SkipProcessingFormats []imagetype.Type
  54. UseLinearColorspace bool
  55. DisableShrinkOnLoad bool
  56. Keys [][]byte
  57. Salts [][]byte
  58. SignatureSize int
  59. Secret string
  60. AllowOrigin string
  61. UserAgent string
  62. IgnoreSslVerification bool
  63. DevelopmentErrorsMode bool
  64. AllowedSources []*regexp.Regexp
  65. SanitizeSvg bool
  66. CookiePassthrough bool
  67. CookieBaseURL string
  68. LocalFileSystemRoot string
  69. S3Enabled bool
  70. S3Region string
  71. S3Endpoint string
  72. GCSEnabled bool
  73. GCSKey string
  74. GCSEndpoint string
  75. ABSEnabled bool
  76. ABSName string
  77. ABSKey string
  78. ABSEndpoint string
  79. SwiftEnabled bool
  80. SwiftUsername string
  81. SwiftAPIKey string
  82. SwiftAuthURL string
  83. SwiftDomain string
  84. SwiftTenant string
  85. SwiftAuthVersion int
  86. SwiftConnectTimeoutSeconds int
  87. SwiftTimeoutSeconds int
  88. ETagEnabled bool
  89. ETagBuster string
  90. BaseURL string
  91. Presets []string
  92. OnlyPresets bool
  93. WatermarkData string
  94. WatermarkPath string
  95. WatermarkURL string
  96. WatermarkOpacity float64
  97. FallbackImageData string
  98. FallbackImagePath string
  99. FallbackImageURL string
  100. FallbackImageHTTPCode int
  101. FallbackImageTTL int
  102. DataDogEnable bool
  103. DataDogEnableMetrics bool
  104. NewRelicAppName string
  105. NewRelicKey string
  106. NewRelicLabels map[string]string
  107. PrometheusBind string
  108. PrometheusNamespace string
  109. BugsnagKey string
  110. BugsnagStage string
  111. HoneybadgerKey string
  112. HoneybadgerEnv string
  113. SentryDSN string
  114. SentryEnvironment string
  115. SentryRelease string
  116. AirbrakeProjecID int
  117. AirbrakeProjecKey string
  118. AirbrakeEnv string
  119. ReportDownloadingErrors bool
  120. EnableDebugHeaders bool
  121. FreeMemoryInterval int
  122. DownloadBufferSize int
  123. BufferPoolCalibrationThreshold int
  124. HealthCheckPath string
  125. )
  126. var (
  127. keyPath string
  128. saltPath string
  129. presetsPath string
  130. )
  131. func init() {
  132. Reset()
  133. flag.StringVar(&keyPath, "keypath", "", "path of the file with hex-encoded key")
  134. flag.StringVar(&saltPath, "saltpath", "", "path of the file with hex-encoded salt")
  135. flag.StringVar(&presetsPath, "presets", "", "path of the file with presets")
  136. }
  137. func Reset() {
  138. Network = "tcp"
  139. Bind = ":8080"
  140. ReadTimeout = 10
  141. WriteTimeout = 10
  142. KeepAliveTimeout = 10
  143. DownloadTimeout = 5
  144. Concurrency = runtime.NumCPU() * 2
  145. RequestsQueueSize = 0
  146. MaxClients = 2048
  147. TTL = 31536000
  148. CacheControlPassthrough = false
  149. SetCanonicalHeader = false
  150. SoReuseport = false
  151. PathPrefix = ""
  152. MaxSrcResolution = 16800000
  153. MaxSrcFileSize = 0
  154. MaxAnimationFrames = 1
  155. MaxSvgCheckBytes = 32 * 1024
  156. MaxRedirects = 10
  157. JpegProgressive = false
  158. PngInterlaced = false
  159. PngQuantize = false
  160. PngQuantizationColors = 256
  161. AvifSpeed = 5
  162. Quality = 80
  163. FormatQuality = map[imagetype.Type]int{imagetype.AVIF: 50}
  164. StripMetadata = true
  165. KeepCopyright = true
  166. StripColorProfile = true
  167. AutoRotate = true
  168. EnforceThumbnail = false
  169. ReturnAttachment = false
  170. EnableWebpDetection = false
  171. EnforceWebp = false
  172. EnableAvifDetection = false
  173. EnforceAvif = false
  174. EnableClientHints = false
  175. PreferredFormats = []imagetype.Type{
  176. imagetype.JPEG,
  177. imagetype.PNG,
  178. imagetype.GIF,
  179. imagetype.WEBP,
  180. imagetype.AVIF,
  181. imagetype.ICO,
  182. }
  183. SkipProcessingFormats = make([]imagetype.Type, 0)
  184. UseLinearColorspace = false
  185. DisableShrinkOnLoad = false
  186. Keys = make([][]byte, 0)
  187. Salts = make([][]byte, 0)
  188. SignatureSize = 32
  189. Secret = ""
  190. AllowOrigin = ""
  191. UserAgent = fmt.Sprintf("imgproxy/%s", version.Version())
  192. IgnoreSslVerification = false
  193. DevelopmentErrorsMode = false
  194. AllowedSources = make([]*regexp.Regexp, 0)
  195. SanitizeSvg = true
  196. CookiePassthrough = false
  197. CookieBaseURL = ""
  198. LocalFileSystemRoot = ""
  199. S3Enabled = false
  200. S3Region = ""
  201. S3Endpoint = ""
  202. GCSEnabled = false
  203. GCSKey = ""
  204. ABSEnabled = false
  205. ABSName = ""
  206. ABSKey = ""
  207. ABSEndpoint = ""
  208. SwiftEnabled = false
  209. SwiftUsername = ""
  210. SwiftAPIKey = ""
  211. SwiftAuthURL = ""
  212. SwiftAuthVersion = 0
  213. SwiftTenant = ""
  214. SwiftDomain = ""
  215. SwiftConnectTimeoutSeconds = 10
  216. SwiftTimeoutSeconds = 60
  217. ETagEnabled = false
  218. ETagBuster = ""
  219. BaseURL = ""
  220. Presets = make([]string, 0)
  221. OnlyPresets = false
  222. WatermarkData = ""
  223. WatermarkPath = ""
  224. WatermarkURL = ""
  225. WatermarkOpacity = 1
  226. FallbackImageData = ""
  227. FallbackImagePath = ""
  228. FallbackImageURL = ""
  229. FallbackImageHTTPCode = 200
  230. FallbackImageTTL = 0
  231. DataDogEnable = false
  232. NewRelicAppName = ""
  233. NewRelicKey = ""
  234. NewRelicLabels = make(map[string]string)
  235. PrometheusBind = ""
  236. PrometheusNamespace = ""
  237. BugsnagKey = ""
  238. BugsnagStage = "production"
  239. HoneybadgerKey = ""
  240. HoneybadgerEnv = "production"
  241. SentryDSN = ""
  242. SentryEnvironment = "production"
  243. SentryRelease = fmt.Sprintf("imgproxy@%s", version.Version())
  244. AirbrakeProjecID = 0
  245. AirbrakeProjecKey = ""
  246. AirbrakeEnv = "production"
  247. ReportDownloadingErrors = true
  248. EnableDebugHeaders = false
  249. FreeMemoryInterval = 10
  250. DownloadBufferSize = 0
  251. BufferPoolCalibrationThreshold = 1024
  252. HealthCheckPath = ""
  253. }
  254. func Configure() error {
  255. if port := os.Getenv("PORT"); len(port) > 0 {
  256. Bind = fmt.Sprintf(":%s", port)
  257. }
  258. configurators.String(&Network, "IMGPROXY_NETWORK")
  259. configurators.String(&Bind, "IMGPROXY_BIND")
  260. configurators.Int(&ReadTimeout, "IMGPROXY_READ_TIMEOUT")
  261. configurators.Int(&WriteTimeout, "IMGPROXY_WRITE_TIMEOUT")
  262. configurators.Int(&KeepAliveTimeout, "IMGPROXY_KEEP_ALIVE_TIMEOUT")
  263. configurators.Int(&DownloadTimeout, "IMGPROXY_DOWNLOAD_TIMEOUT")
  264. configurators.Int(&Concurrency, "IMGPROXY_CONCURRENCY")
  265. configurators.Int(&RequestsQueueSize, "IMGPROXY_REQUESTS_QUEUE_SIZE")
  266. configurators.Int(&MaxClients, "IMGPROXY_MAX_CLIENTS")
  267. configurators.Int(&TTL, "IMGPROXY_TTL")
  268. configurators.Bool(&CacheControlPassthrough, "IMGPROXY_CACHE_CONTROL_PASSTHROUGH")
  269. configurators.Bool(&SetCanonicalHeader, "IMGPROXY_SET_CANONICAL_HEADER")
  270. configurators.Bool(&SoReuseport, "IMGPROXY_SO_REUSEPORT")
  271. configurators.String(&PathPrefix, "IMGPROXY_PATH_PREFIX")
  272. configurators.MegaInt(&MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
  273. configurators.Int(&MaxSrcFileSize, "IMGPROXY_MAX_SRC_FILE_SIZE")
  274. configurators.Int(&MaxSvgCheckBytes, "IMGPROXY_MAX_SVG_CHECK_BYTES")
  275. configurators.Int(&MaxAnimationFrames, "IMGPROXY_MAX_ANIMATION_FRAMES")
  276. configurators.Int(&MaxRedirects, "IMGPROXY_MAX_REDIRECTS")
  277. configurators.Patterns(&AllowedSources, "IMGPROXY_ALLOWED_SOURCES")
  278. configurators.Bool(&SanitizeSvg, "IMGPROXY_SANITIZE_SVG")
  279. configurators.Bool(&JpegProgressive, "IMGPROXY_JPEG_PROGRESSIVE")
  280. configurators.Bool(&PngInterlaced, "IMGPROXY_PNG_INTERLACED")
  281. configurators.Bool(&PngQuantize, "IMGPROXY_PNG_QUANTIZE")
  282. configurators.Int(&PngQuantizationColors, "IMGPROXY_PNG_QUANTIZATION_COLORS")
  283. configurators.Int(&AvifSpeed, "IMGPROXY_AVIF_SPEED")
  284. configurators.Int(&Quality, "IMGPROXY_QUALITY")
  285. if err := configurators.ImageTypesQuality(FormatQuality, "IMGPROXY_FORMAT_QUALITY"); err != nil {
  286. return err
  287. }
  288. configurators.Bool(&StripMetadata, "IMGPROXY_STRIP_METADATA")
  289. configurators.Bool(&KeepCopyright, "IMGPROXY_KEEP_COPYRIGHT")
  290. configurators.Bool(&StripColorProfile, "IMGPROXY_STRIP_COLOR_PROFILE")
  291. configurators.Bool(&AutoRotate, "IMGPROXY_AUTO_ROTATE")
  292. configurators.Bool(&EnforceThumbnail, "IMGPROXY_ENFORCE_THUMBNAIL")
  293. configurators.Bool(&ReturnAttachment, "IMGPROXY_RETURN_ATTACHMENT")
  294. configurators.Bool(&EnableWebpDetection, "IMGPROXY_ENABLE_WEBP_DETECTION")
  295. configurators.Bool(&EnforceWebp, "IMGPROXY_ENFORCE_WEBP")
  296. configurators.Bool(&EnableAvifDetection, "IMGPROXY_ENABLE_AVIF_DETECTION")
  297. configurators.Bool(&EnforceAvif, "IMGPROXY_ENFORCE_AVIF")
  298. configurators.Bool(&EnableClientHints, "IMGPROXY_ENABLE_CLIENT_HINTS")
  299. configurators.String(&HealthCheckPath, "IMGPROXY_HEALTH_CHECK_PATH")
  300. if err := configurators.ImageTypes(&PreferredFormats, "IMGPROXY_PREFERRED_FORMATS"); err != nil {
  301. return err
  302. }
  303. if err := configurators.ImageTypes(&SkipProcessingFormats, "IMGPROXY_SKIP_PROCESSING_FORMATS"); err != nil {
  304. return err
  305. }
  306. configurators.Bool(&UseLinearColorspace, "IMGPROXY_USE_LINEAR_COLORSPACE")
  307. configurators.Bool(&DisableShrinkOnLoad, "IMGPROXY_DISABLE_SHRINK_ON_LOAD")
  308. if err := configurators.Hex(&Keys, "IMGPROXY_KEY"); err != nil {
  309. return err
  310. }
  311. if err := configurators.Hex(&Salts, "IMGPROXY_SALT"); err != nil {
  312. return err
  313. }
  314. configurators.Int(&SignatureSize, "IMGPROXY_SIGNATURE_SIZE")
  315. if err := configurators.HexFile(&Keys, keyPath); err != nil {
  316. return err
  317. }
  318. if err := configurators.HexFile(&Salts, saltPath); err != nil {
  319. return err
  320. }
  321. configurators.String(&Secret, "IMGPROXY_SECRET")
  322. configurators.String(&AllowOrigin, "IMGPROXY_ALLOW_ORIGIN")
  323. configurators.String(&UserAgent, "IMGPROXY_USER_AGENT")
  324. configurators.Bool(&IgnoreSslVerification, "IMGPROXY_IGNORE_SSL_VERIFICATION")
  325. configurators.Bool(&DevelopmentErrorsMode, "IMGPROXY_DEVELOPMENT_ERRORS_MODE")
  326. configurators.Bool(&CookiePassthrough, "IMGPROXY_COOKIE_PASSTHROUGH")
  327. configurators.String(&CookieBaseURL, "IMGPROXY_COOKIE_BASE_URL")
  328. configurators.String(&LocalFileSystemRoot, "IMGPROXY_LOCAL_FILESYSTEM_ROOT")
  329. configurators.Bool(&S3Enabled, "IMGPROXY_USE_S3")
  330. configurators.String(&S3Region, "IMGPROXY_S3_REGION")
  331. configurators.String(&S3Endpoint, "IMGPROXY_S3_ENDPOINT")
  332. configurators.Bool(&GCSEnabled, "IMGPROXY_USE_GCS")
  333. configurators.String(&GCSKey, "IMGPROXY_GCS_KEY")
  334. configurators.String(&GCSEndpoint, "IMGPROXY_GCS_ENDPOINT")
  335. configurators.Bool(&ABSEnabled, "IMGPROXY_USE_ABS")
  336. configurators.String(&ABSName, "IMGPROXY_ABS_NAME")
  337. configurators.String(&ABSKey, "IMGPROXY_ABS_KEY")
  338. configurators.String(&ABSEndpoint, "IMGPROXY_ABS_ENDPOINT")
  339. configurators.Bool(&SwiftEnabled, "IMGPROXY_USE_SWIFT")
  340. configurators.String(&SwiftUsername, "IMGPROXY_SWIFT_USERNAME")
  341. configurators.String(&SwiftAPIKey, "IMGPROXY_SWIFT_API_KEY")
  342. configurators.String(&SwiftAuthURL, "IMGPROXY_SWIFT_AUTH_URL")
  343. configurators.String(&SwiftDomain, "IMGPROXY_SWIFT_DOMAIN")
  344. configurators.String(&SwiftTenant, "IMGPROXY_SWIFT_TENANT")
  345. configurators.Int(&SwiftConnectTimeoutSeconds, "IMGPROXY_SWIFT_CONNECT_TIMEOUT_SECONDS")
  346. configurators.Int(&SwiftTimeoutSeconds, "IMGPROXY_SWIFT_TIMEOUT_SECONDS")
  347. configurators.Bool(&ETagEnabled, "IMGPROXY_USE_ETAG")
  348. configurators.String(&ETagBuster, "IMGPROXY_ETAG_BUSTER")
  349. configurators.String(&BaseURL, "IMGPROXY_BASE_URL")
  350. configurators.StringSlice(&Presets, "IMGPROXY_PRESETS")
  351. if err := configurators.StringSliceFile(&Presets, presetsPath); err != nil {
  352. return err
  353. }
  354. configurators.Bool(&OnlyPresets, "IMGPROXY_ONLY_PRESETS")
  355. configurators.String(&WatermarkData, "IMGPROXY_WATERMARK_DATA")
  356. configurators.String(&WatermarkPath, "IMGPROXY_WATERMARK_PATH")
  357. configurators.String(&WatermarkURL, "IMGPROXY_WATERMARK_URL")
  358. configurators.Float(&WatermarkOpacity, "IMGPROXY_WATERMARK_OPACITY")
  359. configurators.String(&FallbackImageData, "IMGPROXY_FALLBACK_IMAGE_DATA")
  360. configurators.String(&FallbackImagePath, "IMGPROXY_FALLBACK_IMAGE_PATH")
  361. configurators.String(&FallbackImageURL, "IMGPROXY_FALLBACK_IMAGE_URL")
  362. configurators.Int(&FallbackImageHTTPCode, "IMGPROXY_FALLBACK_IMAGE_HTTP_CODE")
  363. configurators.Int(&FallbackImageTTL, "IMGPROXY_FALLBACK_IMAGE_TTL")
  364. configurators.Bool(&DataDogEnable, "IMGPROXY_DATADOG_ENABLE")
  365. configurators.Bool(&DataDogEnableMetrics, "IMGPROXY_DATADOG_ENABLE_ADDITIONAL_METRICS")
  366. configurators.String(&NewRelicAppName, "IMGPROXY_NEW_RELIC_APP_NAME")
  367. configurators.String(&NewRelicKey, "IMGPROXY_NEW_RELIC_KEY")
  368. configurators.StringMap(&NewRelicLabels, "IMGPROXY_NEW_RELIC_LABELS")
  369. configurators.String(&PrometheusBind, "IMGPROXY_PROMETHEUS_BIND")
  370. configurators.String(&PrometheusNamespace, "IMGPROXY_PROMETHEUS_NAMESPACE")
  371. configurators.String(&BugsnagKey, "IMGPROXY_BUGSNAG_KEY")
  372. configurators.String(&BugsnagStage, "IMGPROXY_BUGSNAG_STAGE")
  373. configurators.String(&HoneybadgerKey, "IMGPROXY_HONEYBADGER_KEY")
  374. configurators.String(&HoneybadgerEnv, "IMGPROXY_HONEYBADGER_ENV")
  375. configurators.String(&SentryDSN, "IMGPROXY_SENTRY_DSN")
  376. configurators.String(&SentryEnvironment, "IMGPROXY_SENTRY_ENVIRONMENT")
  377. configurators.String(&SentryRelease, "IMGPROXY_SENTRY_RELEASE")
  378. configurators.Int(&AirbrakeProjecID, "IMGPROXY_AIRBRAKE_PROJECT_ID")
  379. configurators.String(&AirbrakeProjecKey, "IMGPROXY_AIRBRAKE_PROJECT_KEY")
  380. configurators.String(&AirbrakeEnv, "IMGPROXY_AIRBRAKE_ENVIRONMENT")
  381. configurators.Bool(&ReportDownloadingErrors, "IMGPROXY_REPORT_DOWNLOADING_ERRORS")
  382. configurators.Bool(&EnableDebugHeaders, "IMGPROXY_ENABLE_DEBUG_HEADERS")
  383. configurators.Int(&FreeMemoryInterval, "IMGPROXY_FREE_MEMORY_INTERVAL")
  384. configurators.Int(&DownloadBufferSize, "IMGPROXY_DOWNLOAD_BUFFER_SIZE")
  385. configurators.Int(&BufferPoolCalibrationThreshold, "IMGPROXY_BUFFER_POOL_CALIBRATION_THRESHOLD")
  386. if len(Keys) != len(Salts) {
  387. return fmt.Errorf("Number of keys and number of salts should be equal. Keys: %d, salts: %d", len(Keys), len(Salts))
  388. }
  389. if len(Keys) == 0 {
  390. log.Warning("No keys defined, so signature checking is disabled")
  391. }
  392. if len(Salts) == 0 {
  393. log.Warning("No salts defined, so signature checking is disabled")
  394. }
  395. if SignatureSize < 1 || SignatureSize > 32 {
  396. return fmt.Errorf("Signature size should be within 1 and 32, now - %d\n", SignatureSize)
  397. }
  398. if len(Bind) == 0 {
  399. return fmt.Errorf("Bind address is not defined")
  400. }
  401. if ReadTimeout <= 0 {
  402. return fmt.Errorf("Read timeout should be greater than 0, now - %d\n", ReadTimeout)
  403. }
  404. if WriteTimeout <= 0 {
  405. return fmt.Errorf("Write timeout should be greater than 0, now - %d\n", WriteTimeout)
  406. }
  407. if KeepAliveTimeout < 0 {
  408. return fmt.Errorf("KeepAlive timeout should be greater than or equal to 0, now - %d\n", KeepAliveTimeout)
  409. }
  410. if DownloadTimeout <= 0 {
  411. return fmt.Errorf("Download timeout should be greater than 0, now - %d\n", DownloadTimeout)
  412. }
  413. if Concurrency <= 0 {
  414. return fmt.Errorf("Concurrency should be greater than 0, now - %d\n", Concurrency)
  415. }
  416. if RequestsQueueSize < 0 {
  417. return fmt.Errorf("Requests queue size should be greater than or equal 0, now - %d\n", RequestsQueueSize)
  418. }
  419. if MaxClients < 0 {
  420. return fmt.Errorf("Concurrency should be greater than or equal 0, now - %d\n", MaxClients)
  421. }
  422. if TTL <= 0 {
  423. return fmt.Errorf("TTL should be greater than 0, now - %d\n", TTL)
  424. }
  425. if MaxSrcResolution <= 0 {
  426. return fmt.Errorf("Max src resolution should be greater than 0, now - %d\n", MaxSrcResolution)
  427. }
  428. if MaxSrcFileSize < 0 {
  429. return fmt.Errorf("Max src file size should be greater than or equal to 0, now - %d\n", MaxSrcFileSize)
  430. }
  431. if MaxAnimationFrames <= 0 {
  432. return fmt.Errorf("Max animation frames should be greater than 0, now - %d\n", MaxAnimationFrames)
  433. }
  434. if PngQuantizationColors < 2 {
  435. return fmt.Errorf("Png quantization colors should be greater than 1, now - %d\n", PngQuantizationColors)
  436. } else if PngQuantizationColors > 256 {
  437. return fmt.Errorf("Png quantization colors can't be greater than 256, now - %d\n", PngQuantizationColors)
  438. }
  439. if AvifSpeed < 0 {
  440. return fmt.Errorf("Avif speed should be greater than 0, now - %d\n", AvifSpeed)
  441. } else if AvifSpeed > 8 {
  442. return fmt.Errorf("Avif speed can't be greater than 8, now - %d\n", AvifSpeed)
  443. }
  444. if Quality <= 0 {
  445. return fmt.Errorf("Quality should be greater than 0, now - %d\n", Quality)
  446. } else if Quality > 100 {
  447. return fmt.Errorf("Quality can't be greater than 100, now - %d\n", Quality)
  448. }
  449. if len(PreferredFormats) == 0 {
  450. return fmt.Errorf("At least one preferred format should be specified")
  451. }
  452. if IgnoreSslVerification {
  453. log.Warning("Ignoring SSL verification is very unsafe")
  454. }
  455. if LocalFileSystemRoot != "" {
  456. stat, err := os.Stat(LocalFileSystemRoot)
  457. if err != nil {
  458. return fmt.Errorf("Cannot use local directory: %s", err)
  459. }
  460. if !stat.IsDir() {
  461. return fmt.Errorf("Cannot use local directory: not a directory")
  462. }
  463. if LocalFileSystemRoot == "/" {
  464. log.Warning("Exposing root via IMGPROXY_LOCAL_FILESYSTEM_ROOT is unsafe")
  465. }
  466. }
  467. if _, ok := os.LookupEnv("IMGPROXY_USE_GCS"); !ok && len(GCSKey) > 0 {
  468. log.Warning("Set IMGPROXY_USE_GCS to true since it may be required by future versions to enable GCS support")
  469. GCSEnabled = true
  470. }
  471. if WatermarkOpacity <= 0 {
  472. return fmt.Errorf("Watermark opacity should be greater than 0")
  473. } else if WatermarkOpacity > 1 {
  474. return fmt.Errorf("Watermark opacity should be less than or equal to 1")
  475. }
  476. if FallbackImageHTTPCode < 100 || FallbackImageHTTPCode > 599 {
  477. return fmt.Errorf("Fallback image HTTP code should be between 100 and 599")
  478. }
  479. if len(PrometheusBind) > 0 && PrometheusBind == Bind {
  480. return fmt.Errorf("Can't use the same binding for the main server and Prometheus")
  481. }
  482. if FreeMemoryInterval <= 0 {
  483. return fmt.Errorf("Free memory interval should be greater than zero")
  484. }
  485. if DownloadBufferSize < 0 {
  486. return fmt.Errorf("Download buffer size should be greater than or equal to 0")
  487. } else if DownloadBufferSize > math.MaxInt32 {
  488. return fmt.Errorf("Download buffer size can't be greater than %d", math.MaxInt32)
  489. }
  490. if BufferPoolCalibrationThreshold < 64 {
  491. return fmt.Errorf("Buffer pool calibration threshold should be greater than or equal to 64")
  492. }
  493. return nil
  494. }