Browse Source

Configure over env variables

DarthSim 8 years ago
parent
commit
3fa721bee0

+ 1 - 1
.gitignore

@@ -1,2 +1,2 @@
 imgproxy
-config.yml
+tmp/

+ 0 - 22
Makefile

@@ -1,22 +0,0 @@
-current_dir := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
-vendor      := $(current_dir)/_vendor
-goenv       := GOPATH="$(vendor):$(GOPATH)"
-
-all: clean vendorize build
-
-clean:
-	rm -rf bin/
-
-vendorize:
-	cd $(current_dir)
-	GOPATH=$(vendor) go get -d
-	find $(vendor) -name ".git" -type d | xargs rm -rf
-
-clean-vendor:
-	rm -rf $(vendor)
-
-hard-vendorize: clean-vendor vendorize
-
-build:
-	cd $(current_dir)
-	$(goenv) go build -v -ldflags '-w -s' -o bin/server

+ 22 - 2
README.md

@@ -2,10 +2,30 @@
 
 Tiny, fast and secure server for processing remote images.
 
+Full README is on the way.
+
+### How to configure
+
+Imgproxy is 12factor-ready and can be configured with env variables:
+
+* IMGPROXY_BIND - TCP address to listen on. Default: :8080;
+* IMGPROXY_READ_TIMEOUT - the maximum duration (seconds) for reading the entire request, including the body. Default: 10;
+* IMGPROXY_WRITE_TIMEOUT - the maximum duration (seconds) for writing the response. Default: 10;
+* IMGPROXY_MAX_SRC_DIMENSION - the maximum dimension of source image. Images with larger size will be rejected. Default: 4096;
+* IMGPROXY_QUALITY - quality of a result image. Default: 80;
+* IMGPROXY_COMPRESSION - compression of a result image. Default: 6;
+* IMGPROXY_KEY - hex-encoded key
+* IMGPROXY_SALT - hex-encoded salt
+
+You can also specify paths to a files with hex-encoded key and salt:
+
+```
+imgproxy -keypath /path/to/file/with/key -salt /path/to/file/with/salt
+```
+
 ### How to generate url path
 
-Full README is on the way. Here is a short sample which shows how to generate url
-path for imgproxy.
+Here is a short ruby sample which shows how to generate url path for imgproxy.
 
 ```ruby
 require 'openssl'

+ 85 - 53
config.go

@@ -1,93 +1,125 @@
 package main
 
 import (
+	"bytes"
 	"encoding/hex"
 	"flag"
 	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
-
-	"gopkg.in/yaml.v2"
+	"strconv"
 )
 
-type config struct {
-	Bind         string
-	ReadTimeout  int `yaml:"read_timeout"`
-	WriteTimeout int `yaml:"write_timeout"`
-
-	Key     string
-	Salt    string
-	KeyBin  []byte
-	SaltBin []byte
+func absPathToFile(path string) string {
+	if filepath.IsAbs(path) {
+		return path
+	}
 
-	MaxSrcDimension int `yaml:"max_src_dimension"`
+	appPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
+	if err != nil {
+		log.Fatalln(err)
+	}
 
-	Quality     int
-	Compression int
+	return filepath.Join(appPath, path)
 }
 
-var conf = config{
-	Bind:            ":8080",
-	MaxSrcDimension: 4096,
+func intEnvConfig(i *int, name string) {
+	if env, err := strconv.Atoi(os.Getenv(name)); err == nil {
+		*i = env
+	}
 }
 
-func absPathToFile(path string) string {
-	if filepath.IsAbs(path) {
-		return path
+func strEnvConfig(s *string, name string) {
+	if env := os.Getenv(name); len(env) > 0 {
+		*s = env
 	}
+}
 
-	appPath, _ := filepath.Abs(filepath.Dir(os.Args[0]))
-	return filepath.Join(appPath, path)
+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)
+		}
+	}
 }
 
-func init() {
-	cpath := flag.String(
-		"config", "./config.yml", "path to configuration file",
-	)
-	flag.Parse()
+func hexFileConfig(b *[]byte, filepath string) {
+	if len(filepath) == 0 {
+		return
+	}
 
-	file, err := os.Open(absPathToFile(*cpath))
+	fullfp := absPathToFile(filepath)
+	f, err := os.Open(fullfp)
 	if err != nil {
-		log.Fatalln(err)
+		log.Fatalf("Can't open file %s\n", fullfp)
 	}
-	defer file.Close()
 
-	cdata, err := ioutil.ReadAll(file)
+	src, err := ioutil.ReadAll(f)
 	if err != nil {
 		log.Fatalln(err)
 	}
 
-	err = yaml.Unmarshal(cdata, &conf)
+	src = bytes.TrimSpace(src)
+
+	dst := make([]byte, hex.DecodedLen(len(src)))
+	n, err := hex.Decode(dst, src)
 	if err != nil {
-		log.Fatalln(err)
+		log.Fatalf("%s expected to contain hex-encoded string\n", fullfp)
 	}
 
-	if len(conf.Bind) == 0 {
-		conf.Bind = ":8080"
-	}
+	*b = dst[:n]
+}
 
-	if conf.MaxSrcDimension == 0 {
-		conf.MaxSrcDimension = 4096
-	}
+type config struct {
+	Bind         string
+	ReadTimeout  int
+	WriteTimeout int
 
-	if conf.KeyBin, err = hex.DecodeString(conf.Key); err != nil {
-		log.Fatalln("Invalid key. Key should be encoded to hex")
-	}
+	MaxSrcDimension int
 
-	if conf.SaltBin, err = hex.DecodeString(conf.Salt); err != nil {
-		log.Fatalln("Invalid salt. Salt should be encoded to hex")
-	}
+	Quality     int
+	Compression int
 
-	if conf.MaxSrcDimension == 0 {
-		conf.MaxSrcDimension = 4096
-	}
+	Key  []byte
+	Salt []byte
+}
 
-	if conf.Quality == 0 {
-		conf.Quality = 80
-	}
+var conf = config{
+	Bind:            ":8080",
+	ReadTimeout:     10,
+	WriteTimeout:    10,
+	MaxSrcDimension: 4096,
+	Quality:         80,
+	Compression:     6,
+}
+
+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")
+
+	intEnvConfig(&conf.MaxSrcDimension, "IMGPROXY_MAX_SRC_DIMENSION")
+
+	intEnvConfig(&conf.Quality, "IMGPROXY_QUALITY")
+	intEnvConfig(&conf.Compression, "IMGPROXY_COMPRESSION")
 
-	if conf.Compression == 0 {
-		conf.Compression = 6
+	hexEnvConfig(&conf.Key, "IMGPROXY_KEY")
+	hexEnvConfig(&conf.Salt, "IMGPROXY_SALT")
+
+	hexFileConfig(&conf.Key, *keypath)
+	hexFileConfig(&conf.Salt, *saltpath)
+
+	if len(conf.Key) == 0 {
+		log.Fatalln("Key is not defined")
+	}
+	if len(conf.Salt) == 0 {
+		log.Fatalln("Salt is not defined")
 	}
 }

+ 0 - 12
config.yml.example

@@ -1,12 +0,0 @@
-bind: ":8080"
-read_timeout: 10
-write_timeout: 10
-
-# key and salt are hex-encoded
-key: 943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881
-salt: 520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5
-
-max_src_dimension: 4096
-
-quality: 80
-compression: 6

+ 2 - 2
crypt.go

@@ -13,8 +13,8 @@ func validatePath(token, path string) error {
 		return errors.New("Invalid token encoding")
 	}
 
-	mac := hmac.New(sha256.New, conf.KeyBin)
-	mac.Write(conf.SaltBin)
+	mac := hmac.New(sha256.New, conf.Key)
+	mac.Write(conf.Salt)
 	mac.Write([]byte(path))
 	expectedMAC := mac.Sum(nil)
 

+ 2 - 2
glide.lock

@@ -1,8 +1,8 @@
 hash: de73486dba2fd32ca4e577ba7baa1552e33431fa2a88c1f34ba9b7af77e9c75b
-updated: 2017-06-20T17:49:53.147746484+03:00
+updated: 2017-06-25T23:28:17.564332341+03:00
 imports:
 - name: github.com/h2non/bimg
-  version: 45f8993550e71ee7b8001d40c681c6c9fa822357
+  version: 32e459e416aa4abab45ba854298602cb9682256d
 - name: github.com/tj/go-debug
   version: ff4a55a20a86994118644bbddc6a216da193cc13
 - name: gopkg.in/yaml.v2

+ 1 - 1
vendor/github.com/h2non/bimg/.travis.yml

@@ -14,7 +14,7 @@ env:
   - LIBVIPS=8.2.3
   - LIBVIPS=8.3.3
   - LIBVIPS=8.4.5
-  - LIBVIPS=8.5.5
+  - LIBVIPS=8.5.6
   - LIBVIPS=master
 
 matrix:

+ 10 - 0
vendor/github.com/h2non/bimg/History.md

@@ -1,4 +1,14 @@
 
+## v1.0.10 / 2017-06-25
+
+  * Merge pull request #164 from greut/length
+  * Add Image.Length()
+  * Merge pull request #163 from greut/libvips856
+  * Run libvips 8.5.6 on Travis.
+  * Merge pull request #161 from henry-blip/master
+  * Expose vips cache memory management functions.
+  * feat(docs): add watermark image note in features
+
 ## v1.0.9 / 2017-05-25
 
   * Merge pull request #156 from Dynom/SmartCropToGravity

+ 1 - 1
vendor/github.com/h2non/bimg/README.md

@@ -42,7 +42,7 @@ If you're using `gopkg.in`, you can still rely in the `v0` without worrying abou
 - Zoom
 - Thumbnail
 - Extract area
-- Watermark (text only)
+- Watermark (using text or image)
 - Gaussian blur effect
 - Custom output color space (RGB, grayscale...)
 - Format conversion (with additional quality/compression settings)

+ 6 - 1
vendor/github.com/h2non/bimg/image.go

@@ -217,7 +217,12 @@ func (i *Image) Size() (ImageSize, error) {
 	return Size(i.buffer)
 }
 
-// Image returns the current resultant image image buffer.
+// Image returns the current resultant image buffer.
 func (i *Image) Image() []byte {
 	return i.buffer
 }
+
+// Length returns the size in bytes of the image buffer.
+func (i *Image) Length() int {
+	return len(i.buffer)
+}

+ 11 - 0
vendor/github.com/h2non/bimg/image_test.go

@@ -475,6 +475,17 @@ func TestImageSmartCrop(t *testing.T) {
 	Write("fixtures/test_smart_crop.jpg", buf)
 }
 
+func TestImageLength(t *testing.T) {
+	i := initImage("test.jpg")
+
+	actual := i.Length()
+	expected := 53653
+
+	if expected != actual {
+		t.Errorf("Size in Bytes of the image doesn't correspond. %d != %d", expected, actual)
+	}
+}
+
 func initImage(file string) *Image {
 	buf, _ := imageBuf(file)
 	return NewImage(buf)

+ 1 - 1
vendor/github.com/h2non/bimg/version.go

@@ -1,4 +1,4 @@
 package bimg
 
 // Version represents the current package semantic version.
-const Version = "1.0.9"
+const Version = "1.0.10"

+ 16 - 0
vendor/github.com/h2non/bimg/vips.go

@@ -130,6 +130,22 @@ func Shutdown() {
 	}
 }
 
+// VipsCacheSetMaxMem Sets the maximum amount of tracked memory allowed before the vips operation cache
+// begins to drop entries.
+func VipsCacheSetMaxMem(maxCacheMem int) {
+	C.vips_cache_set_max_mem(C.size_t(maxCacheMem))
+}
+
+// VipsCacheSetMax sets the maximum number of operations to keep in the vips operation cache.
+func VipsCacheSetMax(maxCacheSize int) {
+	C.vips_cache_set_max(C.int(maxCacheSize))
+}
+
+// VipsCacheDropAll drops the vips operation cache, freeing the allocated memory.
+func VipsCacheDropAll() {
+	C.vips_cache_drop_all()
+}
+
 // VipsDebugInfo outputs to stdout libvips collected data. Useful for debugging.
 func VipsDebugInfo() {
 	C.im__print_all()