mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-10-09 11:42:48 +02:00
Presets 🎉
This commit is contained in:
43
config.go
43
config.go
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"flag"
|
"flag"
|
||||||
@@ -10,6 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func intEnvConfig(i *int, name string) {
|
func intEnvConfig(i *int, name string) {
|
||||||
@@ -73,6 +75,32 @@ func hexFileConfig(b *[]byte, filepath string) {
|
|||||||
*b = dst[:n]
|
*b = dst[:n]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func presetEnvConfig(p *presets, name string) {
|
||||||
|
if env := os.Getenv(name); len(env) > 0 {
|
||||||
|
presetStrings := strings.Split(env, ",")
|
||||||
|
|
||||||
|
for _, presetStr := range presetStrings {
|
||||||
|
parsePreset(p, presetStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func presetFileConfig(p *presets, filepath string) {
|
||||||
|
if len(filepath) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Can't open file %s\n", filepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
for scanner.Scan() {
|
||||||
|
parsePreset(p, scanner.Text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Bind string
|
Bind string
|
||||||
ReadTimeout int
|
ReadTimeout int
|
||||||
@@ -105,6 +133,8 @@ type config struct {
|
|||||||
ETagEnabled bool
|
ETagEnabled bool
|
||||||
|
|
||||||
BaseURL string
|
BaseURL string
|
||||||
|
|
||||||
|
Presets presets
|
||||||
}
|
}
|
||||||
|
|
||||||
var conf = config{
|
var conf = config{
|
||||||
@@ -123,8 +153,9 @@ var conf = config{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
keypath := flag.String("keypath", "", "path of the file with hex-encoded key")
|
keyPath := flag.String("keypath", "", "path of the file with hex-encoded key")
|
||||||
saltpath := flag.String("saltpath", "", "path of the file with hex-encoded salt")
|
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")
|
showVersion := flag.Bool("v", false, "show version")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
@@ -157,8 +188,8 @@ func init() {
|
|||||||
hexEnvConfig(&conf.Key, "IMGPROXY_KEY")
|
hexEnvConfig(&conf.Key, "IMGPROXY_KEY")
|
||||||
hexEnvConfig(&conf.Salt, "IMGPROXY_SALT")
|
hexEnvConfig(&conf.Salt, "IMGPROXY_SALT")
|
||||||
|
|
||||||
hexFileConfig(&conf.Key, *keypath)
|
hexFileConfig(&conf.Key, *keyPath)
|
||||||
hexFileConfig(&conf.Salt, *saltpath)
|
hexFileConfig(&conf.Salt, *saltPath)
|
||||||
|
|
||||||
strEnvConfig(&conf.Secret, "IMGPROXY_SECRET")
|
strEnvConfig(&conf.Secret, "IMGPROXY_SECRET")
|
||||||
|
|
||||||
@@ -172,6 +203,10 @@ func init() {
|
|||||||
|
|
||||||
strEnvConfig(&conf.BaseURL, "IMGPROXY_BASE_URL")
|
strEnvConfig(&conf.BaseURL, "IMGPROXY_BASE_URL")
|
||||||
|
|
||||||
|
conf.Presets = make(presets)
|
||||||
|
presetEnvConfig(&conf.Presets, "IMGPROXY_PRESETS")
|
||||||
|
presetFileConfig(&conf.Presets, *presetsPath)
|
||||||
|
|
||||||
if len(conf.Key) == 0 {
|
if len(conf.Key) == 0 {
|
||||||
log.Fatalln("Key is not defined")
|
log.Fatalln("Key is not defined")
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -43,3 +44,7 @@ func stacktrace(skip int) string {
|
|||||||
|
|
||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func warning(f string, args ...interface{}) {
|
||||||
|
log.Printf("[WARNING] %s", fmt.Sprintf(f, args...))
|
||||||
|
}
|
||||||
|
40
presets.go
Normal file
40
presets.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type presets map[string]urlOptions
|
||||||
|
|
||||||
|
func parsePreset(p *presets, presetStr string) {
|
||||||
|
presetStr = strings.Trim(presetStr, " ")
|
||||||
|
|
||||||
|
if len(presetStr) == 0 || strings.HasPrefix(presetStr, "#") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(presetStr, "=")
|
||||||
|
|
||||||
|
if len(parts) != 2 {
|
||||||
|
warning("Invalid preset string, omitted: %s", presetStr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name := strings.Trim(parts[0], " ")
|
||||||
|
if len(name) == 0 {
|
||||||
|
warning("Empty preset name, omitted: %s", presetStr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
value := strings.Trim(parts[1], " ")
|
||||||
|
if len(value) == 0 {
|
||||||
|
warning("Empty preset value, omitted: %s", presetStr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
optsStr := strings.Split(value, "/")
|
||||||
|
|
||||||
|
if opts, rest := parseURLOptions(optsStr); len(rest) == 0 {
|
||||||
|
(*p)[name] = opts
|
||||||
|
} else {
|
||||||
|
warning("Invalid preset value, omitted: %s", presetStr)
|
||||||
|
}
|
||||||
|
}
|
@@ -15,6 +15,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type urlOptions map[string][]string
|
||||||
|
|
||||||
type imageType int
|
type imageType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -242,6 +244,22 @@ func applySharpenOption(po *processingOptions, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyPresetOption(po *processingOptions, args []string) error {
|
||||||
|
for _, preset := range args {
|
||||||
|
if p, ok := conf.Presets[preset]; ok {
|
||||||
|
for name, pargs := range p {
|
||||||
|
if err := applyProcessingOption(po, name, pargs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Unknown asset: %s", preset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func applyFormatOption(po *processingOptions, imgType imageType) error {
|
func applyFormatOption(po *processingOptions, imgType imageType) error {
|
||||||
if !vipsTypeSupportSave[imgType] {
|
if !vipsTypeSupportSave[imgType] {
|
||||||
return errors.New("Resulting image type not supported")
|
return errors.New("Resulting image type not supported")
|
||||||
@@ -286,30 +304,53 @@ func applyProcessingOption(po *processingOptions, name string, args []string) er
|
|||||||
if err := applySharpenOption(po, args); err != nil {
|
if err := applySharpenOption(po, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "preset":
|
||||||
|
if err := applyPresetOption(po, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePathAdvanced(parts []string) (string, processingOptions, error) {
|
func parseURLOptions(opts []string) (urlOptions, []string) {
|
||||||
var urlStart int
|
parsed := make(urlOptions)
|
||||||
|
urlStart := len(opts) + 1
|
||||||
|
|
||||||
po := defaultProcessingOptions()
|
for i, opt := range opts {
|
||||||
|
args := strings.Split(opt, ":")
|
||||||
for i, part := range parts {
|
|
||||||
args := strings.Split(part, ":")
|
|
||||||
|
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
urlStart = i
|
urlStart = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := applyProcessingOption(&po, args[0], args[1:]); err != nil {
|
parsed[args[0]] = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
var rest []string
|
||||||
|
|
||||||
|
if urlStart < len(opts) {
|
||||||
|
rest = opts[urlStart:]
|
||||||
|
} else {
|
||||||
|
rest = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed, rest
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePathAdvanced(parts []string) (string, processingOptions, error) {
|
||||||
|
po := defaultProcessingOptions()
|
||||||
|
|
||||||
|
options, urlParts := parseURLOptions(parts)
|
||||||
|
|
||||||
|
for name, args := range options {
|
||||||
|
if err := applyProcessingOption(&po, name, args); err != nil {
|
||||||
return "", po, err
|
return "", po, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
url, imgType, err := decodeURL(parts[urlStart:])
|
url, imgType, err := decodeURL(urlParts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", po, err
|
return "", po, err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user