config.go 24 KB

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