config.go 20 KB

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