config.go 22 KB

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