config.go 21 KB

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