1
0

config.go 17 KB

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