config.go 20 KB

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