1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-03-17 20:17:48 +02:00
imgproxy/config.go

645 lines
19 KiB
Go
Raw Normal View History

2017-06-20 16:58:55 +03:00
package main
import (
2018-09-07 23:41:06 +06:00
"bufio"
2017-06-20 16:58:55 +03:00
"encoding/hex"
"flag"
"fmt"
2019-08-13 17:25:54 +06:00
"math"
2017-06-20 16:58:55 +03:00
"os"
2017-09-28 23:17:23 +06:00
"runtime"
2017-06-26 01:20:48 +03:00
"strconv"
2018-09-07 23:41:06 +06:00
"strings"
2017-06-20 16:58:55 +03:00
)
2017-06-26 01:20:48 +03:00
func intEnvConfig(i *int, name string) {
if env, err := strconv.Atoi(os.Getenv(name)); err == nil {
*i = env
}
2017-06-20 16:58:55 +03:00
}
2018-10-19 15:47:11 +06:00
func floatEnvConfig(i *float64, name string) {
if env, err := strconv.ParseFloat(os.Getenv(name), 64); err == nil {
*i = env
}
}
func megaIntEnvConfig(f *int, name string) {
if env, err := strconv.ParseFloat(os.Getenv(name), 64); err == nil {
*f = int(env * 1000000)
}
}
2017-06-26 01:20:48 +03:00
func strEnvConfig(s *string, name string) {
if env := os.Getenv(name); len(env) > 0 {
*s = env
2017-06-20 16:58:55 +03:00
}
2017-06-26 01:20:48 +03:00
}
2017-06-20 16:58:55 +03:00
func strSliceEnvConfig(s *[]string, name string) {
if env := os.Getenv(name); len(env) > 0 {
parts := strings.Split(env, ",")
for i, p := range parts {
parts[i] = strings.TrimSpace(p)
}
*s = parts
2020-01-13 20:00:50 +06:00
return
}
*s = []string{}
}
func boolEnvConfig(b *bool, name string) {
if env, err := strconv.ParseBool(os.Getenv(name)); err == nil {
*b = env
}
}
func imageTypesEnvConfig(it *[]imageType, name string) {
*it = []imageType{}
if env := os.Getenv(name); len(env) > 0 {
parts := strings.Split(env, ",")
for _, p := range parts {
pt := strings.TrimSpace(p)
if t, ok := imageTypes[pt]; ok {
*it = append(*it, t)
} else {
logWarning("Unknown image format to skip: %s", pt)
}
}
}
}
2021-01-13 17:58:36 +06:00
func formatQualityEnvConfig(m map[imageType]int, name string) {
if env := os.Getenv(name); len(env) > 0 {
parts := strings.Split(env, ",")
for _, p := range parts {
i := strings.Index(p, "=")
if i < 0 {
logWarning("Invalid format quality string: %s", p)
continue
}
imgtypeStr, qStr := strings.TrimSpace(p[:i]), strings.TrimSpace(p[i+1:])
imgtype, ok := imageTypes[imgtypeStr]
if !ok {
logWarning("Invalid format: %s", p)
}
q, err := strconv.Atoi(qStr)
if err != nil || q <= 0 || q > 100 {
logWarning("Invalid quality: %s", p)
}
m[imgtype] = q
}
}
}
2020-02-27 21:44:59 +06:00
func hexEnvConfig(b *[]securityKey, name string) error {
2017-06-26 01:20:48 +03:00
var err error
if env := os.Getenv(name); len(env) > 0 {
2018-11-15 18:35:06 +06:00
parts := strings.Split(env, ",")
keys := make([]securityKey, len(parts))
for i, part := range parts {
if keys[i], err = hex.DecodeString(part); err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("%s expected to be hex-encoded strings. Invalid: %s\n", name, part)
2018-11-15 18:35:06 +06:00
}
2017-06-26 01:20:48 +03:00
}
2018-11-15 18:35:06 +06:00
*b = keys
2017-06-26 01:20:48 +03:00
}
2020-02-27 21:44:59 +06:00
return nil
2017-06-20 16:58:55 +03:00
}
2020-02-27 21:44:59 +06:00
func hexFileConfig(b *[]securityKey, filepath string) error {
2017-06-26 01:20:48 +03:00
if len(filepath) == 0 {
2020-02-27 21:44:59 +06:00
return nil
2017-06-26 01:20:48 +03:00
}
2017-06-20 16:58:55 +03:00
2017-06-27 11:29:57 +03:00
f, err := os.Open(filepath)
2017-06-20 16:58:55 +03:00
if err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Can't open file %s\n", filepath)
2017-06-20 16:58:55 +03:00
}
2018-11-15 18:35:06 +06:00
keys := []securityKey{}
2017-06-20 16:58:55 +03:00
2018-11-15 18:35:06 +06:00
scanner := bufio.NewScanner(f)
for scanner.Scan() {
part := scanner.Text()
2017-06-26 01:20:48 +03:00
2018-11-15 18:35:06 +06:00
if len(part) == 0 {
continue
}
if key, err := hex.DecodeString(part); err == nil {
keys = append(keys, key)
} else {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("%s expected to contain hex-encoded strings. Invalid: %s\n", filepath, part)
2018-11-15 18:35:06 +06:00
}
}
if err := scanner.Err(); err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Failed to read file %s: %s", filepath, err)
2017-06-20 16:58:55 +03:00
}
2018-11-15 18:35:06 +06:00
*b = keys
2020-02-27 21:44:59 +06:00
return nil
2017-06-26 01:20:48 +03:00
}
2017-06-20 16:58:55 +03:00
2020-02-27 21:44:59 +06:00
func presetEnvConfig(p presets, name string) error {
2018-09-07 23:41:06 +06:00
if env := os.Getenv(name); len(env) > 0 {
presetStrings := strings.Split(env, ",")
for _, presetStr := range presetStrings {
2018-11-06 17:19:34 +06:00
if err := parsePreset(p, presetStr); err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf(err.Error())
2018-11-06 17:19:34 +06:00
}
2018-09-07 23:41:06 +06:00
}
}
2020-02-27 21:44:59 +06:00
return nil
2018-09-07 23:41:06 +06:00
}
2020-02-27 21:44:59 +06:00
func presetFileConfig(p presets, filepath string) error {
2018-09-07 23:41:06 +06:00
if len(filepath) == 0 {
2020-02-27 21:44:59 +06:00
return nil
2018-09-07 23:41:06 +06:00
}
f, err := os.Open(filepath)
if err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Can't open file %s\n", filepath)
2018-09-07 23:41:06 +06:00
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
2018-11-06 17:19:34 +06:00
if err := parsePreset(p, scanner.Text()); err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf(err.Error())
2018-11-06 17:19:34 +06:00
}
2018-09-07 23:41:06 +06:00
}
if err := scanner.Err(); err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Failed to read presets file: %s", err)
}
2020-02-27 21:44:59 +06:00
return nil
2018-09-07 23:41:06 +06:00
}
2017-06-26 01:20:48 +03:00
type config struct {
2020-02-03 18:03:18 +06:00
Network string
2019-06-21 16:32:37 +06:00
Bind string
ReadTimeout int
WriteTimeout int
KeepAliveTimeout int
DownloadTimeout int
Concurrency int
MaxClients int
TTL int
CacheControlPassthrough bool
SetCanonicalHeader bool
SoReuseport bool
2017-07-03 16:10:44 +06:00
2020-04-07 17:54:00 +06:00
PathPrefix string
2019-06-11 21:42:21 +06:00
MaxSrcDimension int
MaxSrcResolution int
MaxSrcFileSize int
MaxAnimationFrames int
2020-02-11 19:28:13 +06:00
MaxSvgCheckBytes int
2017-06-20 16:58:55 +03:00
2019-04-05 16:30:16 +06:00
JpegProgressive bool
PngInterlaced bool
PngQuantize bool
PngQuantizationColors int
AvifSpeed int
2019-04-05 16:30:16 +06:00
Quality int
2021-01-13 17:58:36 +06:00
FormatQuality map[imageType]int
2019-04-05 16:30:16 +06:00
GZipCompression int
StripMetadata bool
2021-01-12 20:43:09 +06:00
StripColorProfile bool
AutoRotate bool
2017-06-20 16:58:55 +03:00
2018-09-11 18:26:27 +06:00
EnableWebpDetection bool
EnforceWebp bool
EnableAvifDetection bool
EnforceAvif bool
EnableClientHints bool
2018-09-11 18:26:27 +06:00
SkipProcessingFormats []imageType
UseLinearColorspace bool
DisableShrinkOnLoad bool
2018-11-15 18:35:06 +06:00
Keys []securityKey
Salts []securityKey
AllowInsecure bool
SignatureSize int
Secret string
2018-04-26 17:22:31 +06:00
AllowOrigin string
UserAgent string
IgnoreSslVerification bool
2019-05-08 20:51:39 +06:00
DevelopmentErrorsMode bool
AllowedSources []string
LocalFileSystemRoot string
S3Enabled bool
2018-11-13 19:23:59 +06:00
S3Region string
S3Endpoint string
GCSEnabled bool
2018-10-30 18:12:56 +06:00
GCSKey string
2020-11-19 20:47:18 +06:00
ABSEnabled bool
ABSName string
ABSKey string
ABSEndpoint string
2018-02-26 15:41:37 +06:00
ETagEnabled bool
2018-04-26 17:38:40 +06:00
BaseURL string
2018-09-07 23:41:06 +06:00
Presets presets
OnlyPresets bool
2018-10-19 15:47:11 +06:00
WatermarkData string
WatermarkPath string
WatermarkURL string
WatermarkOpacity float64
2018-10-25 19:24:34 +06:00
FallbackImageData string
FallbackImagePath string
FallbackImageURL string
2018-10-25 19:24:34 +06:00
NewRelicAppName string
NewRelicKey string
2018-10-29 18:04:47 +06:00
PrometheusBind string
PrometheusNamespace string
2018-11-14 19:41:16 +06:00
BugsnagKey string
BugsnagStage string
HoneybadgerKey string
HoneybadgerEnv string
SentryDSN string
SentryEnvironment string
SentryRelease string
AirbrakeProjecId int
AirbrakeProjecKey string
AirbrakeEnv string
ReportDownloadingErrors bool
EnableDebugHeaders bool
FreeMemoryInterval int
DownloadBufferSize int
GZipBufferSize int
BufferPoolCalibrationThreshold int
2017-06-26 01:20:48 +03:00
}
2017-06-20 16:58:55 +03:00
2017-06-26 01:20:48 +03:00
var conf = config{
2020-02-03 18:03:18 +06:00
Network: "tcp",
Bind: ":8080",
ReadTimeout: 10,
WriteTimeout: 10,
2019-06-21 16:32:37 +06:00
KeepAliveTimeout: 10,
DownloadTimeout: 5,
Concurrency: runtime.NumCPU() * 2,
TTL: 3600,
MaxSrcResolution: 16800000,
2019-06-11 21:42:21 +06:00
MaxAnimationFrames: 1,
2020-02-11 19:28:13 +06:00
MaxSvgCheckBytes: 32 * 1024,
SignatureSize: 32,
2019-04-05 16:30:16 +06:00
PngQuantizationColors: 256,
Quality: 80,
AvifSpeed: 5,
2021-01-13 17:58:36 +06:00
FormatQuality: map[imageType]int{imageTypeAVIF: 50},
StripMetadata: true,
2021-01-12 20:43:09 +06:00
StripColorProfile: true,
AutoRotate: true,
UserAgent: fmt.Sprintf("imgproxy/%s", version),
Presets: make(presets),
WatermarkOpacity: 1,
BugsnagStage: "production",
HoneybadgerEnv: "production",
SentryEnvironment: "production",
SentryRelease: fmt.Sprintf("imgproxy/%s", version),
AirbrakeEnv: "production",
ReportDownloadingErrors: true,
FreeMemoryInterval: 10,
BufferPoolCalibrationThreshold: 1024,
2017-06-26 01:20:48 +03:00
}
2020-02-27 21:44:59 +06:00
func configure() error {
2018-09-07 23:41:06 +06:00
keyPath := flag.String("keypath", "", "path of the file with hex-encoded key")
saltPath := flag.String("saltpath", "", "path of the file with hex-encoded salt")
presetsPath := flag.String("presets", "", "path of the file with presets")
2017-06-26 01:20:48 +03:00
flag.Parse()
if port := os.Getenv("PORT"); len(port) > 0 {
conf.Bind = fmt.Sprintf(":%s", port)
}
2020-02-03 18:03:18 +06:00
strEnvConfig(&conf.Network, "IMGPROXY_NETWORK")
2017-06-26 01:20:48 +03:00
strEnvConfig(&conf.Bind, "IMGPROXY_BIND")
intEnvConfig(&conf.ReadTimeout, "IMGPROXY_READ_TIMEOUT")
intEnvConfig(&conf.WriteTimeout, "IMGPROXY_WRITE_TIMEOUT")
2019-06-21 16:32:37 +06:00
intEnvConfig(&conf.KeepAliveTimeout, "IMGPROXY_KEEP_ALIVE_TIMEOUT")
2017-07-05 18:28:22 +06:00
intEnvConfig(&conf.DownloadTimeout, "IMGPROXY_DOWNLOAD_TIMEOUT")
2017-07-04 20:05:53 +06:00
intEnvConfig(&conf.Concurrency, "IMGPROXY_CONCURRENCY")
2017-09-15 13:29:51 +03:00
intEnvConfig(&conf.MaxClients, "IMGPROXY_MAX_CLIENTS")
2017-06-26 01:20:48 +03:00
2017-07-03 16:10:44 +06:00
intEnvConfig(&conf.TTL, "IMGPROXY_TTL")
boolEnvConfig(&conf.CacheControlPassthrough, "IMGPROXY_CACHE_CONTROL_PASSTHROUGH")
boolEnvConfig(&conf.SetCanonicalHeader, "IMGPROXY_SET_CANONICAL_HEADER")
2017-07-03 16:10:44 +06:00
2019-06-27 14:00:39 +06:00
boolEnvConfig(&conf.SoReuseport, "IMGPROXY_SO_REUSEPORT")
2020-04-07 17:54:00 +06:00
strEnvConfig(&conf.PathPrefix, "IMGPROXY_PATH_PREFIX")
2017-06-26 01:20:48 +03:00
intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
megaIntEnvConfig(&conf.MaxSrcResolution, "IMGPROXY_MAX_SRC_RESOLUTION")
2019-01-21 16:36:31 +06:00
intEnvConfig(&conf.MaxSrcFileSize, "IMGPROXY_MAX_SRC_FILE_SIZE")
2020-02-11 19:28:13 +06:00
intEnvConfig(&conf.MaxSvgCheckBytes, "IMGPROXY_MAX_SVG_CHECK_BYTES")
2019-06-11 21:42:21 +06:00
if _, ok := os.LookupEnv("IMGPROXY_MAX_GIF_FRAMES"); ok {
logWarning("`IMGPROXY_MAX_GIF_FRAMES` is deprecated and will be removed in future versions. Use `IMGPROXY_MAX_ANIMATION_FRAMES` instead")
intEnvConfig(&conf.MaxAnimationFrames, "IMGPROXY_MAX_GIF_FRAMES")
}
intEnvConfig(&conf.MaxAnimationFrames, "IMGPROXY_MAX_ANIMATION_FRAMES")
2017-06-26 01:20:48 +03:00
strSliceEnvConfig(&conf.AllowedSources, "IMGPROXY_ALLOWED_SOURCES")
2019-12-25 14:49:20 +06:00
intEnvConfig(&conf.AvifSpeed, "IMGPROXY_AVIF_SPEED")
boolEnvConfig(&conf.JpegProgressive, "IMGPROXY_JPEG_PROGRESSIVE")
boolEnvConfig(&conf.PngInterlaced, "IMGPROXY_PNG_INTERLACED")
2019-04-05 16:30:16 +06:00
boolEnvConfig(&conf.PngQuantize, "IMGPROXY_PNG_QUANTIZE")
intEnvConfig(&conf.PngQuantizationColors, "IMGPROXY_PNG_QUANTIZATION_COLORS")
2017-06-26 01:20:48 +03:00
intEnvConfig(&conf.Quality, "IMGPROXY_QUALITY")
2021-01-13 17:58:36 +06:00
formatQualityEnvConfig(conf.FormatQuality, "IMGPROXY_FORMAT_QUALITY")
2017-06-27 03:41:37 +03:00
intEnvConfig(&conf.GZipCompression, "IMGPROXY_GZIP_COMPRESSION")
boolEnvConfig(&conf.StripMetadata, "IMGPROXY_STRIP_METADATA")
2021-01-12 20:43:09 +06:00
boolEnvConfig(&conf.StripColorProfile, "IMGPROXY_STRIP_COLOR_PROFILE")
boolEnvConfig(&conf.AutoRotate, "IMGPROXY_AUTO_ROTATE")
2017-06-20 16:58:55 +03:00
2018-09-11 18:26:27 +06:00
boolEnvConfig(&conf.EnableWebpDetection, "IMGPROXY_ENABLE_WEBP_DETECTION")
boolEnvConfig(&conf.EnforceWebp, "IMGPROXY_ENFORCE_WEBP")
boolEnvConfig(&conf.EnableAvifDetection, "IMGPROXY_ENABLE_AVIF_DETECTION")
boolEnvConfig(&conf.EnforceAvif, "IMGPROXY_ENFORCE_AVIF")
boolEnvConfig(&conf.EnableClientHints, "IMGPROXY_ENABLE_CLIENT_HINTS")
2018-09-11 18:26:27 +06:00
imageTypesEnvConfig(&conf.SkipProcessingFormats, "IMGPROXY_SKIP_PROCESSING_FORMATS")
boolEnvConfig(&conf.UseLinearColorspace, "IMGPROXY_USE_LINEAR_COLORSPACE")
boolEnvConfig(&conf.DisableShrinkOnLoad, "IMGPROXY_DISABLE_SHRINK_ON_LOAD")
2020-02-27 21:44:59 +06:00
if err := hexEnvConfig(&conf.Keys, "IMGPROXY_KEY"); err != nil {
return err
}
if err := hexEnvConfig(&conf.Salts, "IMGPROXY_SALT"); err != nil {
return err
}
intEnvConfig(&conf.SignatureSize, "IMGPROXY_SIGNATURE_SIZE")
2017-06-26 01:20:48 +03:00
2020-02-27 21:44:59 +06:00
if err := hexFileConfig(&conf.Keys, *keyPath); err != nil {
return err
}
if err := hexFileConfig(&conf.Salts, *saltPath); err != nil {
return err
}
2017-06-26 01:20:48 +03:00
strEnvConfig(&conf.Secret, "IMGPROXY_SECRET")
2018-04-26 17:22:31 +06:00
strEnvConfig(&conf.AllowOrigin, "IMGPROXY_ALLOW_ORIGIN")
strEnvConfig(&conf.UserAgent, "IMGPROXY_USER_AGENT")
boolEnvConfig(&conf.IgnoreSslVerification, "IMGPROXY_IGNORE_SSL_VERIFICATION")
2019-05-08 20:51:39 +06:00
boolEnvConfig(&conf.DevelopmentErrorsMode, "IMGPROXY_DEVELOPMENT_ERRORS_MODE")
strEnvConfig(&conf.LocalFileSystemRoot, "IMGPROXY_LOCAL_FILESYSTEM_ROOT")
2018-02-26 15:41:37 +06:00
2018-05-26 16:22:41 +02:00
boolEnvConfig(&conf.S3Enabled, "IMGPROXY_USE_S3")
2018-11-13 19:23:59 +06:00
strEnvConfig(&conf.S3Region, "IMGPROXY_S3_REGION")
strEnvConfig(&conf.S3Endpoint, "IMGPROXY_S3_ENDPOINT")
boolEnvConfig(&conf.GCSEnabled, "IMGPROXY_USE_GCS")
2018-10-30 18:12:56 +06:00
strEnvConfig(&conf.GCSKey, "IMGPROXY_GCS_KEY")
2018-05-26 16:22:41 +02:00
2020-11-19 20:47:18 +06:00
boolEnvConfig(&conf.ABSEnabled, "IMGPROXY_USE_ABS")
strEnvConfig(&conf.ABSName, "IMGPROXY_ABS_NAME")
strEnvConfig(&conf.ABSKey, "IMGPROXY_ABS_KEY")
strEnvConfig(&conf.ABSEndpoint, "IMGPROXY_ABS_ENDPOINT")
boolEnvConfig(&conf.ETagEnabled, "IMGPROXY_USE_ETAG")
2018-04-26 17:38:40 +06:00
strEnvConfig(&conf.BaseURL, "IMGPROXY_BASE_URL")
2020-02-27 21:44:59 +06:00
if err := presetEnvConfig(conf.Presets, "IMGPROXY_PRESETS"); err != nil {
return err
}
if err := presetFileConfig(conf.Presets, *presetsPath); err != nil {
return err
}
boolEnvConfig(&conf.OnlyPresets, "IMGPROXY_ONLY_PRESETS")
2018-09-07 23:41:06 +06:00
2018-10-19 15:47:11 +06:00
strEnvConfig(&conf.WatermarkData, "IMGPROXY_WATERMARK_DATA")
strEnvConfig(&conf.WatermarkPath, "IMGPROXY_WATERMARK_PATH")
strEnvConfig(&conf.WatermarkURL, "IMGPROXY_WATERMARK_URL")
floatEnvConfig(&conf.WatermarkOpacity, "IMGPROXY_WATERMARK_OPACITY")
strEnvConfig(&conf.FallbackImageData, "IMGPROXY_FALLBACK_IMAGE_DATA")
strEnvConfig(&conf.FallbackImagePath, "IMGPROXY_FALLBACK_IMAGE_PATH")
strEnvConfig(&conf.FallbackImageURL, "IMGPROXY_FALLBACK_IMAGE_URL")
2018-10-25 19:24:34 +06:00
strEnvConfig(&conf.NewRelicAppName, "IMGPROXY_NEW_RELIC_APP_NAME")
strEnvConfig(&conf.NewRelicKey, "IMGPROXY_NEW_RELIC_KEY")
2018-10-29 18:04:47 +06:00
strEnvConfig(&conf.PrometheusBind, "IMGPROXY_PROMETHEUS_BIND")
strEnvConfig(&conf.PrometheusNamespace, "IMGPROXY_PROMETHEUS_NAMESPACE")
2018-10-29 18:04:47 +06:00
2018-11-14 19:41:16 +06:00
strEnvConfig(&conf.BugsnagKey, "IMGPROXY_BUGSNAG_KEY")
strEnvConfig(&conf.BugsnagStage, "IMGPROXY_BUGSNAG_STAGE")
strEnvConfig(&conf.HoneybadgerKey, "IMGPROXY_HONEYBADGER_KEY")
strEnvConfig(&conf.HoneybadgerEnv, "IMGPROXY_HONEYBADGER_ENV")
strEnvConfig(&conf.SentryDSN, "IMGPROXY_SENTRY_DSN")
strEnvConfig(&conf.SentryEnvironment, "IMGPROXY_SENTRY_ENVIRONMENT")
strEnvConfig(&conf.SentryRelease, "IMGPROXY_SENTRY_RELEASE")
intEnvConfig(&conf.AirbrakeProjecId, "IMGPROXY_AIRBRAKE_PROJECT_ID")
strEnvConfig(&conf.AirbrakeProjecKey, "IMGPROXY_AIRBRAKE_PROJECT_KEY")
strEnvConfig(&conf.AirbrakeEnv, "IMGPROXY_AIRBRAKE_ENVIRONMENT")
boolEnvConfig(&conf.ReportDownloadingErrors, "IMGPROXY_REPORT_DOWNLOADING_ERRORS")
boolEnvConfig(&conf.EnableDebugHeaders, "IMGPROXY_ENABLE_DEBUG_HEADERS")
2018-11-14 19:41:16 +06:00
intEnvConfig(&conf.FreeMemoryInterval, "IMGPROXY_FREE_MEMORY_INTERVAL")
intEnvConfig(&conf.DownloadBufferSize, "IMGPROXY_DOWNLOAD_BUFFER_SIZE")
intEnvConfig(&conf.GZipBufferSize, "IMGPROXY_GZIP_BUFFER_SIZE")
intEnvConfig(&conf.BufferPoolCalibrationThreshold, "IMGPROXY_BUFFER_POOL_CALIBRATION_THRESHOLD")
2018-11-15 18:35:06 +06:00
if len(conf.Keys) != len(conf.Salts) {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Number of keys and number of salts should be equal. Keys: %d, salts: %d", len(conf.Keys), len(conf.Salts))
2018-11-15 18:35:06 +06:00
}
if len(conf.Keys) == 0 {
2019-01-11 21:01:48 +06:00
logWarning("No keys defined, so signature checking is disabled")
conf.AllowInsecure = true
2017-06-26 01:20:48 +03:00
}
2018-11-15 18:35:06 +06:00
if len(conf.Salts) == 0 {
2019-01-11 21:01:48 +06:00
logWarning("No salts defined, so signature checking is disabled")
conf.AllowInsecure = true
2017-06-20 16:58:55 +03:00
}
2018-11-15 18:35:06 +06:00
if conf.SignatureSize < 1 || conf.SignatureSize > 32 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Signature size should be within 1 and 32, now - %d\n", conf.SignatureSize)
}
if len(conf.Bind) == 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Bind address is not defined")
}
if conf.ReadTimeout <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Read timeout should be greater than 0, now - %d\n", conf.ReadTimeout)
}
if conf.WriteTimeout <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Write timeout should be greater than 0, now - %d\n", conf.WriteTimeout)
}
2019-06-21 16:32:37 +06:00
if conf.KeepAliveTimeout < 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("KeepAlive timeout should be greater than or equal to 0, now - %d\n", conf.KeepAliveTimeout)
2019-06-21 16:32:37 +06:00
}
2017-07-05 18:28:22 +06:00
if conf.DownloadTimeout <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Download timeout should be greater than 0, now - %d\n", conf.DownloadTimeout)
2017-07-05 18:28:22 +06:00
}
2017-07-04 20:05:53 +06:00
if conf.Concurrency <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Concurrency should be greater than 0, now - %d\n", conf.Concurrency)
2017-07-04 20:05:53 +06:00
}
2017-09-15 13:29:51 +03:00
if conf.MaxClients <= 0 {
2018-03-19 15:06:08 +06:00
conf.MaxClients = conf.Concurrency * 10
2017-09-15 13:29:51 +03:00
}
2017-07-03 16:10:44 +06:00
if conf.TTL <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("TTL should be greater than 0, now - %d\n", conf.TTL)
2017-07-03 16:10:44 +06:00
}
2018-11-15 19:25:53 +06:00
if conf.MaxSrcDimension < 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Max src dimension should be greater than or equal to 0, now - %d\n", conf.MaxSrcDimension)
2018-11-15 19:25:53 +06:00
} else if conf.MaxSrcDimension > 0 {
2019-01-11 21:01:48 +06:00
logWarning("IMGPROXY_MAX_SRC_DIMENSION is deprecated and can be removed in future versions. Use IMGPROXY_MAX_SRC_RESOLUTION")
}
if conf.MaxSrcResolution <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Max src resolution should be greater than 0, now - %d\n", conf.MaxSrcResolution)
}
2019-01-21 16:36:31 +06:00
if conf.MaxSrcFileSize < 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Max src file size should be greater than or equal to 0, now - %d\n", conf.MaxSrcFileSize)
2019-01-21 16:36:31 +06:00
}
2019-06-11 21:42:21 +06:00
if conf.MaxAnimationFrames <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Max animation frames should be greater than 0, now - %d\n", conf.MaxAnimationFrames)
2018-11-15 20:04:12 +06:00
}
2019-04-05 16:30:16 +06:00
if conf.PngQuantizationColors < 2 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Png quantization colors should be greater than 1, now - %d\n", conf.PngQuantizationColors)
2019-04-05 16:30:16 +06:00
} else if conf.PngQuantizationColors > 256 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Png quantization colors can't be greater than 256, now - %d\n", conf.PngQuantizationColors)
2019-04-05 16:30:16 +06:00
}
if conf.Quality <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Quality should be greater than 0, now - %d\n", conf.Quality)
} else if conf.Quality > 100 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Quality can't be greater than 100, now - %d\n", conf.Quality)
}
if conf.AvifSpeed <= 0 {
return fmt.Errorf("Avif speed should be greater than 0, now - %d\n", conf.AvifSpeed)
} else if conf.AvifSpeed > 8 {
return fmt.Errorf("Avif speed can't be greater than 8, now - %d\n", conf.AvifSpeed)
}
if conf.GZipCompression < 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("GZip compression should be greater than or equal to 0, now - %d\n", conf.GZipCompression)
} else if conf.GZipCompression > 9 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("GZip compression can't be greater than 9, now - %d\n", conf.GZipCompression)
}
2017-09-27 14:42:49 +06:00
2019-08-19 14:54:29 +06:00
if conf.GZipCompression > 0 {
logWarning("GZip compression is deprecated and can be removed in future versions")
}
if conf.IgnoreSslVerification {
2019-01-11 21:01:48 +06:00
logWarning("Ignoring SSL verification is very unsafe")
}
if conf.LocalFileSystemRoot != "" {
stat, err := os.Stat(conf.LocalFileSystemRoot)
if err != nil {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Cannot use local directory: %s", err)
}
if !stat.IsDir() {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Cannot use local directory: not a directory")
}
if conf.LocalFileSystemRoot == "/" {
logWarning("Exposing root via IMGPROXY_LOCAL_FILESYSTEM_ROOT is unsafe")
}
}
if _, ok := os.LookupEnv("IMGPROXY_USE_GCS"); !ok && len(conf.GCSKey) > 0 {
logWarning("Set IMGPROXY_USE_GCS to true since it may be required by future versions to enable GCS support")
conf.GCSEnabled = true
}
2018-10-19 15:47:11 +06:00
if conf.WatermarkOpacity <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Watermark opacity should be greater than 0")
2018-10-19 15:47:11 +06:00
} else if conf.WatermarkOpacity > 1 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Watermark opacity should be less than or equal to 1")
2018-10-19 15:47:11 +06:00
}
2018-10-29 18:04:47 +06:00
if len(conf.PrometheusBind) > 0 && conf.PrometheusBind == conf.Bind {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Can't use the same binding for the main server and Prometheus")
2018-10-29 18:04:47 +06:00
}
if conf.FreeMemoryInterval <= 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Free memory interval should be greater than zero")
}
if conf.DownloadBufferSize < 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Download buffer size should be greater than or equal to 0")
2019-08-13 17:25:54 +06:00
} else if conf.DownloadBufferSize > math.MaxInt32 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Download buffer size can't be greater than %d", math.MaxInt32)
}
if conf.GZipBufferSize < 0 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("GZip buffer size should be greater than or equal to 0")
2019-08-13 17:25:54 +06:00
} else if conf.GZipBufferSize > math.MaxInt32 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("GZip buffer size can't be greater than %d", math.MaxInt32)
}
if conf.BufferPoolCalibrationThreshold < 64 {
2020-02-27 21:44:59 +06:00
return fmt.Errorf("Buffer pool calibration threshold should be greater than or equal to 64")
}
2020-02-27 21:44:59 +06:00
return nil
2017-06-20 16:58:55 +03:00
}