2017-06-20 15:58:55 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-06-26 00:20:48 +02:00
|
|
|
"bytes"
|
2017-06-20 15:58:55 +02:00
|
|
|
"encoding/hex"
|
|
|
|
"flag"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"os"
|
2017-06-26 00:20:48 +02:00
|
|
|
"strconv"
|
2017-06-20 15:58:55 +02:00
|
|
|
)
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
func intEnvConfig(i *int, name string) {
|
|
|
|
if env, err := strconv.Atoi(os.Getenv(name)); err == nil {
|
|
|
|
*i = env
|
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
func strEnvConfig(s *string, name string) {
|
|
|
|
if env := os.Getenv(name); len(env) > 0 {
|
|
|
|
*s = env
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|
2017-06-26 00:20:48 +02:00
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
func hexEnvConfig(b *[]byte, name string) {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if env := os.Getenv(name); len(env) > 0 {
|
|
|
|
if *b, err = hex.DecodeString(env); err != nil {
|
|
|
|
log.Fatalf("%s expected to be hex-encoded string\n", name)
|
|
|
|
}
|
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
func hexFileConfig(b *[]byte, filepath string) {
|
|
|
|
if len(filepath) == 0 {
|
|
|
|
return
|
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-27 10:29:57 +02:00
|
|
|
f, err := os.Open(filepath)
|
2017-06-20 15:58:55 +02:00
|
|
|
if err != nil {
|
2017-06-27 10:29:57 +02:00
|
|
|
log.Fatalf("Can't open file %s\n", filepath)
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
src, err := ioutil.ReadAll(f)
|
2017-06-20 15:58:55 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err)
|
|
|
|
}
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
src = bytes.TrimSpace(src)
|
|
|
|
|
|
|
|
dst := make([]byte, hex.DecodedLen(len(src)))
|
|
|
|
n, err := hex.Decode(dst, src)
|
2017-06-20 15:58:55 +02:00
|
|
|
if err != nil {
|
2017-06-27 10:29:57 +02:00
|
|
|
log.Fatalf("%s expected to contain hex-encoded string\n", filepath)
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
*b = dst[:n]
|
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
type config struct {
|
2017-07-05 14:28:22 +02:00
|
|
|
Bind string
|
|
|
|
ReadTimeout int
|
|
|
|
WriteTimeout int
|
|
|
|
DownloadTimeout int
|
|
|
|
Concurrency int
|
2017-09-15 12:29:51 +02:00
|
|
|
MaxClients int
|
2017-07-05 14:28:22 +02:00
|
|
|
TTL int
|
2017-07-03 12:10:44 +02:00
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
MaxSrcDimension int
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-27 02:41:37 +02:00
|
|
|
Quality int
|
|
|
|
GZipCompression int
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
Key []byte
|
|
|
|
Salt []byte
|
2017-07-01 23:25:08 +02:00
|
|
|
|
|
|
|
Secret string
|
2017-06-26 00:20:48 +02:00
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
var conf = config{
|
|
|
|
Bind: ":8080",
|
|
|
|
ReadTimeout: 10,
|
|
|
|
WriteTimeout: 10,
|
2017-07-05 14:28:22 +02:00
|
|
|
DownloadTimeout: 5,
|
2017-07-04 16:05:53 +02:00
|
|
|
Concurrency: 100,
|
2017-07-03 12:10:44 +02:00
|
|
|
TTL: 3600,
|
2017-06-26 00:20:48 +02:00
|
|
|
MaxSrcDimension: 4096,
|
|
|
|
Quality: 80,
|
2017-06-27 02:41:37 +02:00
|
|
|
GZipCompression: 5,
|
2017-06-26 00:20:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
keypath := flag.String("keypath", "", "path of the file with hex-encoded key")
|
|
|
|
saltpath := flag.String("saltpath", "", "path of the file with hex-encoded salt")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
strEnvConfig(&conf.Bind, "IMGPROXY_BIND")
|
|
|
|
intEnvConfig(&conf.ReadTimeout, "IMGPROXY_READ_TIMEOUT")
|
|
|
|
intEnvConfig(&conf.WriteTimeout, "IMGPROXY_WRITE_TIMEOUT")
|
2017-07-05 14:28:22 +02:00
|
|
|
intEnvConfig(&conf.DownloadTimeout, "IMGPROXY_DOWNLOAD_TIMEOUT")
|
2017-07-04 16:05:53 +02:00
|
|
|
intEnvConfig(&conf.Concurrency, "IMGPROXY_CONCURRENCY")
|
2017-09-15 12:29:51 +02:00
|
|
|
intEnvConfig(&conf.MaxClients, "IMGPROXY_MAX_CLIENTS")
|
2017-06-26 00:20:48 +02:00
|
|
|
|
2017-07-03 12:10:44 +02:00
|
|
|
intEnvConfig(&conf.TTL, "IMGPROXY_TTL")
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
|
|
|
|
|
|
|
|
intEnvConfig(&conf.Quality, "IMGPROXY_QUALITY")
|
2017-06-27 02:41:37 +02:00
|
|
|
intEnvConfig(&conf.GZipCompression, "IMGPROXY_GZIP_COMPRESSION")
|
2017-06-20 15:58:55 +02:00
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
hexEnvConfig(&conf.Key, "IMGPROXY_KEY")
|
|
|
|
hexEnvConfig(&conf.Salt, "IMGPROXY_SALT")
|
|
|
|
|
|
|
|
hexFileConfig(&conf.Key, *keypath)
|
|
|
|
hexFileConfig(&conf.Salt, *saltpath)
|
|
|
|
|
2017-07-01 23:25:08 +02:00
|
|
|
strEnvConfig(&conf.Secret, "IMGPROXY_SECRET")
|
|
|
|
|
2017-06-26 00:20:48 +02:00
|
|
|
if len(conf.Key) == 0 {
|
|
|
|
log.Fatalln("Key is not defined")
|
|
|
|
}
|
|
|
|
if len(conf.Salt) == 0 {
|
|
|
|
log.Fatalln("Salt is not defined")
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|
2017-06-27 10:52:54 +02:00
|
|
|
|
|
|
|
if len(conf.Bind) == 0 {
|
|
|
|
log.Fatalln("Bind address is not defined")
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.ReadTimeout <= 0 {
|
|
|
|
log.Fatalf("Read timeout should be greater than 0, now - %d\n", conf.ReadTimeout)
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.WriteTimeout <= 0 {
|
|
|
|
log.Fatalf("Write timeout should be greater than 0, now - %d\n", conf.WriteTimeout)
|
|
|
|
}
|
|
|
|
|
2017-07-05 14:28:22 +02:00
|
|
|
if conf.DownloadTimeout <= 0 {
|
|
|
|
log.Fatalf("Download timeout should be greater than 0, now - %d\n", conf.DownloadTimeout)
|
|
|
|
}
|
|
|
|
|
2017-07-04 16:05:53 +02:00
|
|
|
if conf.Concurrency <= 0 {
|
|
|
|
log.Fatalf("Concurrency should be greater than 0, now - %d\n", conf.Concurrency)
|
|
|
|
}
|
|
|
|
|
2017-09-15 12:29:51 +02:00
|
|
|
if conf.MaxClients <= 0 {
|
|
|
|
conf.MaxClients = conf.Concurrency * 2
|
|
|
|
}
|
|
|
|
|
2017-07-03 12:10:44 +02:00
|
|
|
if conf.TTL <= 0 {
|
|
|
|
log.Fatalf("TTL should be greater than 0, now - %d\n", conf.TTL)
|
|
|
|
}
|
|
|
|
|
2017-06-27 10:52:54 +02:00
|
|
|
if conf.MaxSrcDimension <= 0 {
|
|
|
|
log.Fatalf("Max src dimension should be greater than 0, now - %d\n", conf.MaxSrcDimension)
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.Quality <= 0 {
|
|
|
|
log.Fatalf("Quality should be greater than 0, now - %d\n", conf.Quality)
|
|
|
|
} else if conf.Quality > 100 {
|
|
|
|
log.Fatalf("Quality can't be greater than 100, now - %d\n", conf.Quality)
|
|
|
|
}
|
|
|
|
|
|
|
|
if conf.GZipCompression < 0 {
|
|
|
|
log.Fatalf("GZip compression should be greater than or quual to 0, now - %d\n", conf.GZipCompression)
|
|
|
|
} else if conf.GZipCompression > 9 {
|
|
|
|
log.Fatalf("GZip compression can't be greater than 9, now - %d\n", conf.GZipCompression)
|
|
|
|
}
|
2017-06-20 15:58:55 +02:00
|
|
|
}
|