|
@@ -58,7 +58,7 @@ func boolEnvConfig(b *bool, name string) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func hexEnvConfig(b *[]securityKey, name string) {
|
|
|
+func hexEnvConfig(b *[]securityKey, name string) error {
|
|
|
var err error
|
|
|
|
|
|
if env := os.Getenv(name); len(env) > 0 {
|
|
@@ -68,22 +68,24 @@ func hexEnvConfig(b *[]securityKey, name string) {
|
|
|
|
|
|
for i, part := range parts {
|
|
|
if keys[i], err = hex.DecodeString(part); err != nil {
|
|
|
- logFatal("%s expected to be hex-encoded strings. Invalid: %s\n", name, part)
|
|
|
+ return fmt.Errorf("%s expected to be hex-encoded strings. Invalid: %s\n", name, part)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
*b = keys
|
|
|
}
|
|
|
+
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func hexFileConfig(b *[]securityKey, filepath string) {
|
|
|
+func hexFileConfig(b *[]securityKey, filepath string) error {
|
|
|
if len(filepath) == 0 {
|
|
|
- return
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
f, err := os.Open(filepath)
|
|
|
if err != nil {
|
|
|
- logFatal("Can't open file %s\n", filepath)
|
|
|
+ return fmt.Errorf("Can't open file %s\n", filepath)
|
|
|
}
|
|
|
|
|
|
keys := []securityKey{}
|
|
@@ -99,49 +101,55 @@ func hexFileConfig(b *[]securityKey, filepath string) {
|
|
|
if key, err := hex.DecodeString(part); err == nil {
|
|
|
keys = append(keys, key)
|
|
|
} else {
|
|
|
- logFatal("%s expected to contain hex-encoded strings. Invalid: %s\n", filepath, part)
|
|
|
+ return fmt.Errorf("%s expected to contain hex-encoded strings. Invalid: %s\n", filepath, part)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
- logFatal("Failed to read file %s: %s", filepath, err)
|
|
|
+ return fmt.Errorf("Failed to read file %s: %s", filepath, err)
|
|
|
}
|
|
|
|
|
|
*b = keys
|
|
|
+
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func presetEnvConfig(p presets, name string) {
|
|
|
+func presetEnvConfig(p presets, name string) error {
|
|
|
if env := os.Getenv(name); len(env) > 0 {
|
|
|
presetStrings := strings.Split(env, ",")
|
|
|
|
|
|
for _, presetStr := range presetStrings {
|
|
|
if err := parsePreset(p, presetStr); err != nil {
|
|
|
- logFatal(err.Error())
|
|
|
+ return fmt.Errorf(err.Error())
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func presetFileConfig(p presets, filepath string) {
|
|
|
+func presetFileConfig(p presets, filepath string) error {
|
|
|
if len(filepath) == 0 {
|
|
|
- return
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
f, err := os.Open(filepath)
|
|
|
if err != nil {
|
|
|
- logFatal("Can't open file %s\n", filepath)
|
|
|
+ return fmt.Errorf("Can't open file %s\n", filepath)
|
|
|
}
|
|
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
|
for scanner.Scan() {
|
|
|
if err := parsePreset(p, scanner.Text()); err != nil {
|
|
|
- logFatal(err.Error())
|
|
|
+ return fmt.Errorf(err.Error())
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
- logFatal("Failed to read presets file: %s", err)
|
|
|
+ return fmt.Errorf("Failed to read presets file: %s", err)
|
|
|
}
|
|
|
+
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
type config struct {
|
|
@@ -263,18 +271,12 @@ var conf = config{
|
|
|
BufferPoolCalibrationThreshold: 1024,
|
|
|
}
|
|
|
|
|
|
-func configure() {
|
|
|
+func configure() error {
|
|
|
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")
|
|
|
- showVersion := flag.Bool("v", false, "show version")
|
|
|
flag.Parse()
|
|
|
|
|
|
- if *showVersion {
|
|
|
- fmt.Println(version)
|
|
|
- os.Exit(0)
|
|
|
- }
|
|
|
-
|
|
|
if port := os.Getenv("PORT"); len(port) > 0 {
|
|
|
conf.Bind = fmt.Sprintf(":%s", port)
|
|
|
}
|
|
@@ -321,12 +323,20 @@ func configure() {
|
|
|
boolEnvConfig(&conf.UseLinearColorspace, "IMGPROXY_USE_LINEAR_COLORSPACE")
|
|
|
boolEnvConfig(&conf.DisableShrinkOnLoad, "IMGPROXY_DISABLE_SHRINK_ON_LOAD")
|
|
|
|
|
|
- hexEnvConfig(&conf.Keys, "IMGPROXY_KEY")
|
|
|
- hexEnvConfig(&conf.Salts, "IMGPROXY_SALT")
|
|
|
+ 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")
|
|
|
|
|
|
- hexFileConfig(&conf.Keys, *keyPath)
|
|
|
- hexFileConfig(&conf.Salts, *saltPath)
|
|
|
+ if err := hexFileConfig(&conf.Keys, *keyPath); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if err := hexFileConfig(&conf.Salts, *saltPath); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
|
|
|
strEnvConfig(&conf.Secret, "IMGPROXY_SECRET")
|
|
|
|
|
@@ -350,8 +360,12 @@ func configure() {
|
|
|
|
|
|
strEnvConfig(&conf.BaseURL, "IMGPROXY_BASE_URL")
|
|
|
|
|
|
- presetEnvConfig(conf.Presets, "IMGPROXY_PRESETS")
|
|
|
- presetFileConfig(conf.Presets, *presetsPath)
|
|
|
+ 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")
|
|
|
|
|
|
strEnvConfig(&conf.WatermarkData, "IMGPROXY_WATERMARK_DATA")
|
|
@@ -379,7 +393,7 @@ func configure() {
|
|
|
intEnvConfig(&conf.BufferPoolCalibrationThreshold, "IMGPROXY_BUFFER_POOL_CALIBRATION_THRESHOLD")
|
|
|
|
|
|
if len(conf.Keys) != len(conf.Salts) {
|
|
|
- logFatal("Number of keys and number of salts should be equal. Keys: %d, salts: %d", len(conf.Keys), len(conf.Salts))
|
|
|
+ return fmt.Errorf("Number of keys and number of salts should be equal. Keys: %d, salts: %d", len(conf.Keys), len(conf.Salts))
|
|
|
}
|
|
|
if len(conf.Keys) == 0 {
|
|
|
logWarning("No keys defined, so signature checking is disabled")
|
|
@@ -391,30 +405,30 @@ func configure() {
|
|
|
}
|
|
|
|
|
|
if conf.SignatureSize < 1 || conf.SignatureSize > 32 {
|
|
|
- logFatal("Signature size should be within 1 and 32, now - %d\n", conf.SignatureSize)
|
|
|
+ return fmt.Errorf("Signature size should be within 1 and 32, now - %d\n", conf.SignatureSize)
|
|
|
}
|
|
|
|
|
|
if len(conf.Bind) == 0 {
|
|
|
- logFatal("Bind address is not defined")
|
|
|
+ return fmt.Errorf("Bind address is not defined")
|
|
|
}
|
|
|
|
|
|
if conf.ReadTimeout <= 0 {
|
|
|
- logFatal("Read timeout should be greater than 0, now - %d\n", conf.ReadTimeout)
|
|
|
+ return fmt.Errorf("Read timeout should be greater than 0, now - %d\n", conf.ReadTimeout)
|
|
|
}
|
|
|
|
|
|
if conf.WriteTimeout <= 0 {
|
|
|
- logFatal("Write timeout should be greater than 0, now - %d\n", conf.WriteTimeout)
|
|
|
+ return fmt.Errorf("Write timeout should be greater than 0, now - %d\n", conf.WriteTimeout)
|
|
|
}
|
|
|
if conf.KeepAliveTimeout < 0 {
|
|
|
- logFatal("KeepAlive timeout should be greater than or equal to 0, now - %d\n", conf.KeepAliveTimeout)
|
|
|
+ return fmt.Errorf("KeepAlive timeout should be greater than or equal to 0, now - %d\n", conf.KeepAliveTimeout)
|
|
|
}
|
|
|
|
|
|
if conf.DownloadTimeout <= 0 {
|
|
|
- logFatal("Download timeout should be greater than 0, now - %d\n", conf.DownloadTimeout)
|
|
|
+ return fmt.Errorf("Download timeout should be greater than 0, now - %d\n", conf.DownloadTimeout)
|
|
|
}
|
|
|
|
|
|
if conf.Concurrency <= 0 {
|
|
|
- logFatal("Concurrency should be greater than 0, now - %d\n", conf.Concurrency)
|
|
|
+ return fmt.Errorf("Concurrency should be greater than 0, now - %d\n", conf.Concurrency)
|
|
|
}
|
|
|
|
|
|
if conf.MaxClients <= 0 {
|
|
@@ -422,43 +436,43 @@ func configure() {
|
|
|
}
|
|
|
|
|
|
if conf.TTL <= 0 {
|
|
|
- logFatal("TTL should be greater than 0, now - %d\n", conf.TTL)
|
|
|
+ return fmt.Errorf("TTL should be greater than 0, now - %d\n", conf.TTL)
|
|
|
}
|
|
|
|
|
|
if conf.MaxSrcDimension < 0 {
|
|
|
- logFatal("Max src dimension should be greater than or equal to 0, now - %d\n", conf.MaxSrcDimension)
|
|
|
+ return fmt.Errorf("Max src dimension should be greater than or equal to 0, now - %d\n", conf.MaxSrcDimension)
|
|
|
} else if conf.MaxSrcDimension > 0 {
|
|
|
logWarning("IMGPROXY_MAX_SRC_DIMENSION is deprecated and can be removed in future versions. Use IMGPROXY_MAX_SRC_RESOLUTION")
|
|
|
}
|
|
|
|
|
|
if conf.MaxSrcResolution <= 0 {
|
|
|
- logFatal("Max src resolution should be greater than 0, now - %d\n", conf.MaxSrcResolution)
|
|
|
+ return fmt.Errorf("Max src resolution should be greater than 0, now - %d\n", conf.MaxSrcResolution)
|
|
|
}
|
|
|
|
|
|
if conf.MaxSrcFileSize < 0 {
|
|
|
- logFatal("Max src file size should be greater than or equal to 0, now - %d\n", conf.MaxSrcFileSize)
|
|
|
+ return fmt.Errorf("Max src file size should be greater than or equal to 0, now - %d\n", conf.MaxSrcFileSize)
|
|
|
}
|
|
|
|
|
|
if conf.MaxAnimationFrames <= 0 {
|
|
|
- logFatal("Max animation frames should be greater than 0, now - %d\n", conf.MaxAnimationFrames)
|
|
|
+ return fmt.Errorf("Max animation frames should be greater than 0, now - %d\n", conf.MaxAnimationFrames)
|
|
|
}
|
|
|
|
|
|
if conf.PngQuantizationColors < 2 {
|
|
|
- logFatal("Png quantization colors should be greater than 1, now - %d\n", conf.PngQuantizationColors)
|
|
|
+ return fmt.Errorf("Png quantization colors should be greater than 1, now - %d\n", conf.PngQuantizationColors)
|
|
|
} else if conf.PngQuantizationColors > 256 {
|
|
|
- logFatal("Png quantization colors can't be greater than 256, now - %d\n", conf.PngQuantizationColors)
|
|
|
+ return fmt.Errorf("Png quantization colors can't be greater than 256, now - %d\n", conf.PngQuantizationColors)
|
|
|
}
|
|
|
|
|
|
if conf.Quality <= 0 {
|
|
|
- logFatal("Quality should be greater than 0, now - %d\n", conf.Quality)
|
|
|
+ return fmt.Errorf("Quality should be greater than 0, now - %d\n", conf.Quality)
|
|
|
} else if conf.Quality > 100 {
|
|
|
- logFatal("Quality can't be greater than 100, now - %d\n", conf.Quality)
|
|
|
+ return fmt.Errorf("Quality can't be greater than 100, now - %d\n", conf.Quality)
|
|
|
}
|
|
|
|
|
|
if conf.GZipCompression < 0 {
|
|
|
- logFatal("GZip compression should be greater than or equal to 0, now - %d\n", conf.GZipCompression)
|
|
|
+ return fmt.Errorf("GZip compression should be greater than or equal to 0, now - %d\n", conf.GZipCompression)
|
|
|
} else if conf.GZipCompression > 9 {
|
|
|
- logFatal("GZip compression can't be greater than 9, now - %d\n", conf.GZipCompression)
|
|
|
+ return fmt.Errorf("GZip compression can't be greater than 9, now - %d\n", conf.GZipCompression)
|
|
|
}
|
|
|
|
|
|
if conf.GZipCompression > 0 {
|
|
@@ -473,11 +487,11 @@ func configure() {
|
|
|
stat, err := os.Stat(conf.LocalFileSystemRoot)
|
|
|
|
|
|
if err != nil {
|
|
|
- logFatal("Cannot use local directory: %s", err)
|
|
|
+ return fmt.Errorf("Cannot use local directory: %s", err)
|
|
|
}
|
|
|
|
|
|
if !stat.IsDir() {
|
|
|
- logFatal("Cannot use local directory: not a directory")
|
|
|
+ return fmt.Errorf("Cannot use local directory: not a directory")
|
|
|
}
|
|
|
|
|
|
if conf.LocalFileSystemRoot == "/" {
|
|
@@ -491,32 +505,34 @@ func configure() {
|
|
|
}
|
|
|
|
|
|
if conf.WatermarkOpacity <= 0 {
|
|
|
- logFatal("Watermark opacity should be greater than 0")
|
|
|
+ return fmt.Errorf("Watermark opacity should be greater than 0")
|
|
|
} else if conf.WatermarkOpacity > 1 {
|
|
|
- logFatal("Watermark opacity should be less than or equal to 1")
|
|
|
+ return fmt.Errorf("Watermark opacity should be less than or equal to 1")
|
|
|
}
|
|
|
|
|
|
if len(conf.PrometheusBind) > 0 && conf.PrometheusBind == conf.Bind {
|
|
|
- logFatal("Can't use the same binding for the main server and Prometheus")
|
|
|
+ return fmt.Errorf("Can't use the same binding for the main server and Prometheus")
|
|
|
}
|
|
|
|
|
|
if conf.FreeMemoryInterval <= 0 {
|
|
|
- logFatal("Free memory interval should be greater than zero")
|
|
|
+ return fmt.Errorf("Free memory interval should be greater than zero")
|
|
|
}
|
|
|
|
|
|
if conf.DownloadBufferSize < 0 {
|
|
|
- logFatal("Download buffer size should be greater than or equal to 0")
|
|
|
+ return fmt.Errorf("Download buffer size should be greater than or equal to 0")
|
|
|
} else if conf.DownloadBufferSize > math.MaxInt32 {
|
|
|
- logFatal("Download buffer size can't be greater than %d", math.MaxInt32)
|
|
|
+ return fmt.Errorf("Download buffer size can't be greater than %d", math.MaxInt32)
|
|
|
}
|
|
|
|
|
|
if conf.GZipBufferSize < 0 {
|
|
|
- logFatal("GZip buffer size should be greater than or equal to 0")
|
|
|
+ return fmt.Errorf("GZip buffer size should be greater than or equal to 0")
|
|
|
} else if conf.GZipBufferSize > math.MaxInt32 {
|
|
|
- logFatal("GZip buffer size can't be greater than %d", math.MaxInt32)
|
|
|
+ return fmt.Errorf("GZip buffer size can't be greater than %d", math.MaxInt32)
|
|
|
}
|
|
|
|
|
|
if conf.BufferPoolCalibrationThreshold < 64 {
|
|
|
- logFatal("Buffer pool calibration threshold should be greater than or equal to 64")
|
|
|
+ return fmt.Errorf("Buffer pool calibration threshold should be greater than or equal to 64")
|
|
|
}
|
|
|
+
|
|
|
+ return nil
|
|
|
}
|