config.go 25 KB

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