/
resizr.go
152 lines (132 loc) · 4.19 KB
/
resizr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"flag"
"fmt"
. "github.com/tj/go-debug"
"io/ioutil"
"os"
"runtime"
d "runtime/debug"
"strconv"
"time"
)
var debug = Debug("resizr")
var (
aAddr = flag.String("a", "", "bind address")
aPort = flag.Int("p", 9000, "port to listen")
aVers = flag.Bool("v", false, "Show version")
aVersl = flag.Bool("version", false, "Show version")
aHelp = flag.Bool("h", false, "Show help")
aHelpl = flag.Bool("help", false, "Show help")
aCors = flag.Bool("cors", false, "Enable CORS support")
aGzip = flag.Bool("gzip", false, "Enable gzip compression")
aPlaceholder = flag.String("placeholder", "", "Image path to placeholder")
aKey = flag.String("key", "", "Define API key for authorization")
aCertFile = flag.String("certfile", "", "TLS certificate file path")
aKeyFile = flag.String("keyfile", "", "TLS private key file path")
aReadTimeout = flag.Int("http-read-timeout", 30, "HTTP read timeout in seconds")
aWriteTimeout = flag.Int("http-write-timeout", 30, "HTTP write timeout in seconds")
aConcurrency = flag.Int("concurrency", 0, "Throttle concurrency limit per second")
aBurst = flag.Int("burst", 100, "Throttle burst max cache size")
aMRelease = flag.Int("mrelease", 30, "OS memory release inverval in seconds")
aCpus = flag.Int("cpus", runtime.GOMAXPROCS(-1), "Number of cpu cores to use")
)
const usage = `resizr %s
Usage:
resizr -p 80
resizr -cors
Options:
-a <addr> bind address [default: *]
-p <port> bind port [default: 9000]
-h, -help output help
-v, -version output version
-placeholder <path> placeholder image to use on error
-cors Enable CORS support [default: false]
-gzip Enable gzip compression [default: false]
-key <key> Define API key for authorization
-http-read-timeout <num> HTTP read timeout in seconds [default: 30]
-http-write-timeout <num> HTTP write timeout in seconds [default: 30]
-certfile <path> TLS certificate file path
-keyfile <path> TLS private key file path
-concurreny <num> Throttle concurrency limit per second [default: disabled]
-burst <num> Throttle burst max cache size [default: 100]
-mrelease <num> OS memory release inverval in seconds [default: 30]
-cpus <num> Number of used cpu cores.
(default for current machine is %d cores)
`
func main() {
var err error
flag.Usage = func() {
fmt.Fprint(os.Stderr, fmt.Sprintf(usage, Version, runtime.NumCPU()))
}
flag.Parse()
if *aHelp || *aHelpl {
showUsage()
}
if *aVers || *aVersl {
showVersion()
}
// Only required in Go < 1.5
runtime.GOMAXPROCS(*aCpus)
port := getPort(*aPort)
opts := ServerOptions{
Port: port,
Address: *aAddr,
Gzip: *aGzip,
CORS: *aCors,
ApiKey: *aKey,
Concurrency: *aConcurrency,
Burst: *aBurst,
CertFile: *aCertFile,
KeyFile: *aKeyFile,
HttpReadTimeout: *aReadTimeout,
HttpWriteTimeout: *aWriteTimeout,
}
// Load placeholder image
if *aPlaceholder != "" {
opts.Placeholder, err = ioutil.ReadFile(*aPlaceholder)
if err != nil {
exitWithError("cannot read placeholder image")
}
}
// Create a memory release goroutine
if *aMRelease > 0 {
memoryRelease(*aMRelease)
}
debug("resizr server listening on port %d", port)
// Start the server
err = Server(opts)
if err != nil {
exitWithError("cannot start the server: %s\n", err)
}
}
func getPort(port int) int {
if portEnv := os.Getenv("PORT"); portEnv != "" {
newPort, _ := strconv.Atoi(portEnv)
if newPort > 0 {
port = newPort
}
}
return port
}
func showUsage() {
flag.Usage()
os.Exit(1)
}
func showVersion() {
fmt.Println(Version)
os.Exit(1)
}
func memoryRelease(interval int) {
ticker := time.NewTicker(time.Duration(interval) * time.Second)
go func() {
for _ = range ticker.C {
debug("FreeOSMemory()")
d.FreeOSMemory()
}
}()
}
func exitWithError(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, format, args)
os.Exit(1)
}