mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Configure over env variables
This commit is contained in:
parent
a7da9207be
commit
3fa721bee0
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
imgproxy
|
||||
config.yml
|
||||
tmp/
|
||||
|
22
Makefile
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
|
24
README.md
24
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'
|
||||
|
176
config.go
176
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
|
||||
|
||||
MaxSrcDimension int `yaml:"max_src_dimension"`
|
||||
|
||||
Quality int
|
||||
Compression int
|
||||
}
|
||||
|
||||
var conf = config{
|
||||
Bind: ":8080",
|
||||
MaxSrcDimension: 4096,
|
||||
}
|
||||
|
||||
func absPathToFile(path string) string {
|
||||
if filepath.IsAbs(path) {
|
||||
return path
|
||||
}
|
||||
|
||||
appPath, _ := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
appPath, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
return filepath.Join(appPath, path)
|
||||
}
|
||||
|
||||
func init() {
|
||||
cpath := flag.String(
|
||||
"config", "./config.yml", "path to configuration file",
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
file, err := os.Open(absPathToFile(*cpath))
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
cdata, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(cdata, &conf)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if len(conf.Bind) == 0 {
|
||||
conf.Bind = ":8080"
|
||||
}
|
||||
|
||||
if conf.MaxSrcDimension == 0 {
|
||||
conf.MaxSrcDimension = 4096
|
||||
}
|
||||
|
||||
if conf.KeyBin, err = hex.DecodeString(conf.Key); err != nil {
|
||||
log.Fatalln("Invalid key. Key should be encoded to hex")
|
||||
}
|
||||
|
||||
if conf.SaltBin, err = hex.DecodeString(conf.Salt); err != nil {
|
||||
log.Fatalln("Invalid salt. Salt should be encoded to hex")
|
||||
}
|
||||
|
||||
if conf.MaxSrcDimension == 0 {
|
||||
conf.MaxSrcDimension = 4096
|
||||
}
|
||||
|
||||
if conf.Quality == 0 {
|
||||
conf.Quality = 80
|
||||
}
|
||||
|
||||
if conf.Compression == 0 {
|
||||
conf.Compression = 6
|
||||
func intEnvConfig(i *int, name string) {
|
||||
if env, err := strconv.Atoi(os.Getenv(name)); err == nil {
|
||||
*i = env
|
||||
}
|
||||
}
|
||||
|
||||
func strEnvConfig(s *string, name string) {
|
||||
if env := os.Getenv(name); len(env) > 0 {
|
||||
*s = env
|
||||
}
|
||||
}
|
||||
|
||||
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 hexFileConfig(b *[]byte, filepath string) {
|
||||
if len(filepath) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
fullfp := absPathToFile(filepath)
|
||||
f, err := os.Open(fullfp)
|
||||
if err != nil {
|
||||
log.Fatalf("Can't open file %s\n", fullfp)
|
||||
}
|
||||
|
||||
src, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
src = bytes.TrimSpace(src)
|
||||
|
||||
dst := make([]byte, hex.DecodedLen(len(src)))
|
||||
n, err := hex.Decode(dst, src)
|
||||
if err != nil {
|
||||
log.Fatalf("%s expected to contain hex-encoded string\n", fullfp)
|
||||
}
|
||||
|
||||
*b = dst[:n]
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Bind string
|
||||
ReadTimeout int
|
||||
WriteTimeout int
|
||||
|
||||
MaxSrcDimension int
|
||||
|
||||
Quality int
|
||||
Compression int
|
||||
|
||||
Key []byte
|
||||
Salt []byte
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
@ -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
|
4
crypt.go
4
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)
|
||||
|
||||
|
4
glide.lock
generated
4
glide.lock
generated
@ -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
|
||||
|
2
vendor/github.com/h2non/bimg/.travis.yml
generated
vendored
2
vendor/github.com/h2non/bimg/.travis.yml
generated
vendored
@ -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
vendor/github.com/h2non/bimg/History.md
generated
vendored
10
vendor/github.com/h2non/bimg/History.md
generated
vendored
@ -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
|
||||
|
2
vendor/github.com/h2non/bimg/README.md
generated
vendored
2
vendor/github.com/h2non/bimg/README.md
generated
vendored
@ -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)
|
||||
|
7
vendor/github.com/h2non/bimg/image.go
generated
vendored
7
vendor/github.com/h2non/bimg/image.go
generated
vendored
@ -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
vendor/github.com/h2non/bimg/image_test.go
generated
vendored
11
vendor/github.com/h2non/bimg/image_test.go
generated
vendored
@ -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)
|
||||
|
2
vendor/github.com/h2non/bimg/version.go
generated
vendored
2
vendor/github.com/h2non/bimg/version.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
package bimg
|
||||
|
||||
// Version represents the current package semantic version.
|
||||
const Version = "1.0.9"
|
||||
const Version = "1.0.10"
|
||||
|
16
vendor/github.com/h2non/bimg/vips.go
generated
vendored
16
vendor/github.com/h2non/bimg/vips.go
generated
vendored
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user