mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 13:42:02 +08:00
Feature: Add Compression rate on header (#59)
* Add X-Compression-Rate on response header * add test case for compression rate, change logging and other improvements * move config to config.go, add header for safari and proxyMode, logging improvement * update gitignore for remote-raw and coverage.txt * Refine log level
This commit is contained in:
parent
1881ae83cc
commit
9eda9ee799
2
.gitignore
vendored
2
.gitignore
vendored
@ -19,3 +19,5 @@ exhaust/
|
||||
/.idea/modules.xml
|
||||
/.idea/vcs.xml
|
||||
/.idea/webp_server_go.iml
|
||||
remote-raw/
|
||||
coverage.txt
|
59
config.go
Normal file
59
config.go
Normal file
@ -0,0 +1,59 @@
|
||||
// webp_server_go - config
|
||||
// 2020-11-27 13:05
|
||||
// Benny <benny.think@gmail.com>
|
||||
|
||||
package main
|
||||
|
||||
type Config struct {
|
||||
Host string `json:"HOST"`
|
||||
Port string `json:"PORT"`
|
||||
ImgPath string `json:"IMG_PATH"`
|
||||
Quality string `json:"QUALITY"`
|
||||
AllowedTypes []string `json:"ALLOWED_TYPES"`
|
||||
ExhaustPath string `json:"EXHAUST_PATH"`
|
||||
}
|
||||
|
||||
var (
|
||||
configPath string
|
||||
jobs int
|
||||
dumpConfig, dumpSystemd bool
|
||||
verboseMode, showVersion bool
|
||||
prefetch, proxyMode bool
|
||||
|
||||
config Config
|
||||
version = "0.2.2"
|
||||
)
|
||||
|
||||
const (
|
||||
NotCompressed = "not_compressed"
|
||||
WebpBigger = "webp_bigger"
|
||||
)
|
||||
|
||||
const (
|
||||
sampleConfig = `
|
||||
{
|
||||
"HOST": "127.0.0.1",
|
||||
"PORT": "3333",
|
||||
"QUALITY": "80",
|
||||
"IMG_PATH": "./pics",
|
||||
"EXHAUST_PATH": "./exhaust",
|
||||
"ALLOWED_TYPES": ["jpg","png","jpeg","bmp"]
|
||||
}`
|
||||
|
||||
sampleSystemd = `
|
||||
[Unit]
|
||||
Description=WebP Server Go
|
||||
Documentation=https://github.com/webp-sh/webp_server_go
|
||||
After=nginx.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
StandardError=journal
|
||||
WorkingDirectory=/opt/webps
|
||||
ExecStart=/opt/webps/webp-server --config /opt/webps/config.json
|
||||
Restart=always
|
||||
RestartSec=3s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target`
|
||||
)
|
20
helper.go
20
helper.go
@ -91,7 +91,7 @@ func cleanProxyCache(cacheImagePath string) {
|
||||
// Delete /node.png*
|
||||
files, err := filepath.Glob(cacheImagePath + "*")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
log.Infoln(err)
|
||||
}
|
||||
for _, f := range files {
|
||||
if err := os.Remove(f); err != nil {
|
||||
@ -108,7 +108,7 @@ func genWebpAbs(RawImagePath string, ExhaustPath string, ImgFilename string, req
|
||||
return "", ""
|
||||
}
|
||||
ModifiedTime := STAT.ModTime().Unix()
|
||||
// webpFilename: abc.jpg.png -> abc.jpg.png1582558990.webp
|
||||
// webpFilename: abc.jpg.png -> abc.jpg.png.1582558990.webp
|
||||
WebpFilename := fmt.Sprintf("%s.%d.webp", ImgFilename, ModifiedTime)
|
||||
cwd, _ := os.Getwd()
|
||||
|
||||
@ -127,6 +127,22 @@ func genEtag(ImgAbsPath string) string {
|
||||
return fmt.Sprintf(`W/"%d-%08X"`, len(data), crc)
|
||||
}
|
||||
|
||||
func getCompressionRate(RawImagePath string, webpAbsPath string) string {
|
||||
originFileInfo, err := os.Stat(RawImagePath)
|
||||
if err != nil {
|
||||
log.Warnf("fail to get raw image %v", err)
|
||||
return ""
|
||||
}
|
||||
webpFileInfo, err := os.Stat(webpAbsPath)
|
||||
if err != nil {
|
||||
log.Warnf("fail to get webp image %v", err)
|
||||
return ""
|
||||
}
|
||||
compressionRate := float64(webpFileInfo.Size()) / float64(originFileInfo.Size())
|
||||
log.Debugf("The compress rate is %d/%d=%.2f", originFileInfo.Size(), webpFileInfo.Size(), compressionRate)
|
||||
return fmt.Sprintf(`%.2f`, compressionRate)
|
||||
}
|
||||
|
||||
func goOrigin(UA string) bool {
|
||||
// for more information, please check test case
|
||||
if strings.Contains(UA, "Firefox") || strings.Contains(UA, "Chrome") {
|
||||
|
@ -157,3 +157,18 @@ func TestCleanProxyCache(t *testing.T) {
|
||||
// test bad dir
|
||||
cleanProxyCache("/aasdyg/dhj2/dagh")
|
||||
}
|
||||
|
||||
func TestGetCompressionRate(t *testing.T) {
|
||||
pic1 := "pics/webp_server.bmp"
|
||||
pic2 := "pics/webp_server.jpg"
|
||||
var ratio string
|
||||
|
||||
ratio = getCompressionRate(pic1, pic2)
|
||||
assert.Equal(t, "0.16", ratio)
|
||||
|
||||
ratio = getCompressionRate(pic1, "pic2")
|
||||
assert.Equal(t, "", ratio)
|
||||
|
||||
ratio = getCompressionRate("pic1", pic2)
|
||||
assert.Equal(t, "", ratio)
|
||||
}
|
||||
|
17
router.go
17
router.go
@ -20,16 +20,17 @@ func convert(c *fiber.Ctx) error {
|
||||
var imgFilename = path.Base(reqURI) // pure filename, 123.jpg
|
||||
var finalFile string // We'll only need one c.sendFile()
|
||||
var UA = c.Get("User-Agent")
|
||||
done := goOrigin(UA)
|
||||
if done {
|
||||
log.Debugf("Incoming connection from %s@%s with %s", UA, c.IP(), imgFilename)
|
||||
|
||||
needOrigin := goOrigin(UA)
|
||||
if needOrigin {
|
||||
log.Infof("A Safari/IE/whatever user has arrived...%s", UA)
|
||||
// Check for Safari users. If they're Safari, just simply ignore everything.
|
||||
|
||||
etag := genEtag(rawImageAbs)
|
||||
c.Set("ETag", etag)
|
||||
c.Set("X-Compression-Rate", NotCompressed)
|
||||
return c.SendFile(rawImageAbs)
|
||||
}
|
||||
log.Debugf("Incoming connection from %s@%s with %s", UA, c.IP(), imgFilename)
|
||||
|
||||
// check ext
|
||||
var allowed = false
|
||||
@ -43,6 +44,7 @@ func convert(c *fiber.Ctx) error {
|
||||
allowed = false
|
||||
}
|
||||
}
|
||||
|
||||
if !allowed {
|
||||
msg := "File extension not allowed! " + imgFilename
|
||||
log.Warn(msg)
|
||||
@ -60,7 +62,7 @@ func convert(c *fiber.Ctx) error {
|
||||
// https://test.webp.sh/node.png
|
||||
realRemoteAddr := config.ImgPath + reqURI
|
||||
// Ping Remote for status code and etag info
|
||||
fmt.Println("Remote Addr is " + realRemoteAddr + ", fetching..")
|
||||
log.Infof("Remote Addr is %s fetching", realRemoteAddr)
|
||||
statusCode, etagValue := getRemoteImageInfo(realRemoteAddr)
|
||||
if statusCode == 200 {
|
||||
// Check local path: /node.png-etag-<etagValue>
|
||||
@ -77,7 +79,7 @@ func convert(c *fiber.Ctx) error {
|
||||
_ = os.MkdirAll(path.Dir(localEtagImagePath), 0755)
|
||||
err := webpEncoder(localRemoteTmpPath, localEtagImagePath, float32(q), true, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
log.Warning(err)
|
||||
}
|
||||
return c.SendFile(localEtagImagePath)
|
||||
}
|
||||
@ -130,13 +132,14 @@ func convert(c *fiber.Ctx) error {
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
_ = c.SendStatus(400)
|
||||
_ = c.Send([]byte("Bad file!"))
|
||||
_ = c.Send([]byte("Bad file. " + err.Error()))
|
||||
return err
|
||||
}
|
||||
finalFile = webpAbsPath
|
||||
}
|
||||
etag := genEtag(finalFile)
|
||||
c.Set("ETag", etag)
|
||||
c.Set("X-Compression-Rate", getCompressionRate(rawImageAbs, webpAbsPath))
|
||||
return c.SendFile(finalFile)
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,44 @@ var (
|
||||
SafariUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15"
|
||||
)
|
||||
|
||||
func setupParam() {
|
||||
// setup parameters here...
|
||||
config.ImgPath = "./pics"
|
||||
config.ExhaustPath = "./exhaust"
|
||||
config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp"}
|
||||
}
|
||||
|
||||
func requestToServer(url string, app *fiber.App, ua string) (*http.Response, []byte) {
|
||||
req := httptest.NewRequest("GET", url, nil)
|
||||
req.Header.Set("User-Agent", ua)
|
||||
resp, _ := app.Test(req, 60000)
|
||||
data, _ := ioutil.ReadAll(resp.Body)
|
||||
return resp, data
|
||||
}
|
||||
|
||||
func TestServerHeaders(t *testing.T) {
|
||||
setupParam()
|
||||
var app = fiber.New()
|
||||
app.Get("/*", convert)
|
||||
url := "http://127.0.0.1:3333/webp_server.bmp"
|
||||
|
||||
// test for chrome
|
||||
response, _ := requestToServer(url, app, chromeUA)
|
||||
ratio := response.Header.Get("X-Compression-Rate")
|
||||
etag := response.Header.Get("Etag")
|
||||
|
||||
assert.NotEqual(t, "", ratio)
|
||||
assert.NotEqual(t, "", etag)
|
||||
|
||||
// test for safari
|
||||
response, _ = requestToServer(url, app, SafariUA)
|
||||
ratio = response.Header.Get("X-Compression-Rate")
|
||||
etag = response.Header.Get("Etag")
|
||||
|
||||
assert.Equal(t, NotCompressed, ratio)
|
||||
assert.NotEqual(t, "", etag)
|
||||
}
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
setupParam()
|
||||
var testChromeLink = map[string]string{
|
||||
@ -108,20 +146,4 @@ func TestConvertProxyModeWork(t *testing.T) {
|
||||
resp, data := requestToServer(url, app, chromeUA)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(t, "image/webp", getFileContentType(data))
|
||||
|
||||
}
|
||||
|
||||
func setupParam() {
|
||||
// setup parameters here...
|
||||
config.ImgPath = "./pics"
|
||||
config.ExhaustPath = "./exhaust"
|
||||
config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp"}
|
||||
}
|
||||
|
||||
func requestToServer(url string, app *fiber.App, ua string) (*http.Response, []byte) {
|
||||
req := httptest.NewRequest("GET", url, nil)
|
||||
req.Header.Set("User-Agent", ua)
|
||||
resp, _ := app.Test(req, 60000)
|
||||
data, _ := ioutil.ReadAll(resp.Body)
|
||||
return resp, data
|
||||
}
|
||||
|
@ -12,54 +12,6 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Host string `json:"HOST"`
|
||||
Port string `json:"PORT"`
|
||||
ImgPath string `json:"IMG_PATH"`
|
||||
Quality string `json:"QUALITY"`
|
||||
AllowedTypes []string `json:"ALLOWED_TYPES"`
|
||||
ExhaustPath string `json:"EXHAUST_PATH"`
|
||||
}
|
||||
|
||||
var (
|
||||
configPath string
|
||||
jobs int
|
||||
dumpConfig, dumpSystemd, verboseMode, prefetch, showVersion bool
|
||||
|
||||
proxyMode bool
|
||||
config Config
|
||||
version = "0.2.2"
|
||||
)
|
||||
|
||||
const (
|
||||
sampleConfig = `
|
||||
{
|
||||
"HOST": "127.0.0.1",
|
||||
"PORT": "3333",
|
||||
"QUALITY": "80",
|
||||
"IMG_PATH": "./pics",
|
||||
"EXHAUST_PATH": "./exhaust",
|
||||
"ALLOWED_TYPES": ["jpg","png","jpeg","bmp"]
|
||||
}`
|
||||
|
||||
sampleSystemd = `
|
||||
[Unit]
|
||||
Description=WebP Server Go
|
||||
Documentation=https://github.com/webp-sh/webp_server_go
|
||||
After=nginx.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
StandardError=journal
|
||||
WorkingDirectory=/opt/webps
|
||||
ExecStart=/opt/webps/webp-server --config /opt/webps/config.json
|
||||
Restart=always
|
||||
RestartSec=3s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target`
|
||||
)
|
||||
|
||||
func loadConfig(path string) Config {
|
||||
jsonObject, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user