config.go 22 KB

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