mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 13:42:02 +08:00
Better RAM usage (#200)
* Manually close image for GC * Remove config * Handle error by os.Stat * Add more test on fetchRemoteImage * refine TestGenOptimizedAbsPath * Bump version to 0.8.1
This commit is contained in:
parent
651ae512a3
commit
e64ded7f47
@ -31,7 +31,7 @@ var (
|
|||||||
prefetch, proxyMode bool
|
prefetch, proxyMode bool
|
||||||
remoteRaw = "remote-raw"
|
remoteRaw = "remote-raw"
|
||||||
config Config
|
config Config
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
15
encoder.go
15
encoder.go
@ -144,6 +144,7 @@ func avifEncoder(p1, p2 string, quality int, extraParams ExtraParams) error {
|
|||||||
log.Error(err)
|
log.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
img.Close()
|
||||||
|
|
||||||
convertLog("AVIF", p1, p2, quality)
|
convertLog("AVIF", p1, p2, quality)
|
||||||
return nil
|
return nil
|
||||||
@ -191,14 +192,24 @@ func webpEncoder(p1, p2 string, quality int, extraParams ExtraParams) error {
|
|||||||
log.Error(err)
|
log.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
img.Close()
|
||||||
|
|
||||||
convertLog("WebP", p1, p2, quality)
|
convertLog("WebP", p1, p2, quality)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertLog(itype, p1 string, p2 string, quality int) {
|
func convertLog(itype, p1 string, p2 string, quality int) {
|
||||||
oldf, _ := os.Stat(p1)
|
oldf, err := os.Stat(p1)
|
||||||
newf, _ := os.Stat(p2)
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
newf, err := os.Stat(p2)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Infof("%s@%d%%: %s->%s %d->%d %.2f%% deflated", itype, quality,
|
log.Infof("%s@%d%%: %s->%s %d->%d %.2f%% deflated", itype, quality,
|
||||||
p1, p2, oldf.Size(), newf.Size(), float32(newf.Size())/float32(oldf.Size())*100)
|
p1, p2, oldf.Size(), newf.Size(), float32(newf.Size())/float32(oldf.Size())*100)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
@ -8,7 +12,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -45,16 +48,71 @@ func TestImageExists(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenWebpAbs(t *testing.T) {
|
func TestGenOptimizedAbsPath(t *testing.T) {
|
||||||
cwd, cooked := genOptimizedAbsPath("./pics/webp_server.png", "/tmp",
|
// Create a temporary file for testing
|
||||||
"test", "a", ExtraParams{Width: 0, Height: 0})
|
tempFile, err := os.CreateTemp("", "test_image.*")
|
||||||
if !strings.Contains(cwd, "webp_server_go") {
|
if err != nil {
|
||||||
t.Logf("Result: [%v], Expected: [%v]", cwd, "webp_server_go")
|
t.Fatalf("Failed to create temporary file: %v", err)
|
||||||
}
|
}
|
||||||
var parts = strings.Split(cooked, ".")
|
defer os.Remove(tempFile.Name())
|
||||||
|
|
||||||
assert.Equalf(t, parts[0], "/tmp/test", "Result: [%v], Expected: [%v]", cooked, "/tmp/test.<ts>.webp")
|
// Set the modification time for the temporary file
|
||||||
assert.Equalf(t, parts[2], "webp", "Result: [%v], Expected: [%v]", cooked, "/tmp/test.<ts>.webp")
|
modTime := time.Now()
|
||||||
|
if err := os.Chtimes(tempFile.Name(), modTime, modTime); err != nil {
|
||||||
|
t.Fatalf("Failed to set modification time for the temporary file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawImagePath := tempFile.Name()
|
||||||
|
exhaustPath := "/path/to/exhaust"
|
||||||
|
imageName := "tsuki.jpg"
|
||||||
|
reqURI := "/path/to/tsuki.jpg"
|
||||||
|
extraParams := ExtraParams{Width: 200, Height: 0}
|
||||||
|
|
||||||
|
// Test if config.EnableExtraParams is false
|
||||||
|
config.EnableExtraParams = false
|
||||||
|
|
||||||
|
avifAbsolutePath, webpAbsolutePath := genOptimizedAbsPath(rawImagePath, exhaustPath, imageName, reqURI, extraParams)
|
||||||
|
|
||||||
|
expectedAvifPath := path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.avif", imageName, modTime.Unix())))
|
||||||
|
expectedWebpPath := path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.webp", imageName, modTime.Unix())))
|
||||||
|
|
||||||
|
if avifAbsolutePath != expectedAvifPath {
|
||||||
|
t.Errorf("Avif absolute path is incorrect. Expected: %s, Got: %s", expectedAvifPath, avifAbsolutePath)
|
||||||
|
}
|
||||||
|
if webpAbsolutePath != expectedWebpPath {
|
||||||
|
t.Errorf("Webp absolute path is incorrect. Expected: %s, Got: %s", expectedWebpPath, webpAbsolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test if config.EnableExtraParams is true and extraParams is not 0
|
||||||
|
config.EnableExtraParams = true
|
||||||
|
|
||||||
|
avifAbsolutePath, webpAbsolutePath = genOptimizedAbsPath(rawImagePath, exhaustPath, imageName, reqURI, extraParams)
|
||||||
|
|
||||||
|
expectedAvifPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.avif_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
|
||||||
|
expectedWebpPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.webp_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
|
||||||
|
|
||||||
|
if avifAbsolutePath != expectedAvifPath {
|
||||||
|
t.Errorf("Avif absolute path is incorrect. Expected: %s, Got: %s", expectedAvifPath, avifAbsolutePath)
|
||||||
|
}
|
||||||
|
if webpAbsolutePath != expectedWebpPath {
|
||||||
|
t.Errorf("Webp absolute path is incorrect. Expected: %s, Got: %s", expectedWebpPath, webpAbsolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test if config.EnableExtraParams is true and extraParams is 0
|
||||||
|
config.EnableExtraParams = true
|
||||||
|
extraParams = ExtraParams{Width: 200, Height: 0}
|
||||||
|
|
||||||
|
avifAbsolutePath, webpAbsolutePath = genOptimizedAbsPath(rawImagePath, exhaustPath, imageName, reqURI, extraParams)
|
||||||
|
|
||||||
|
expectedAvifPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.avif_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
|
||||||
|
expectedWebpPath = path.Clean(path.Join(exhaustPath, path.Dir(reqURI), fmt.Sprintf("%s.%d.webp_width=%d&height=%d", imageName, modTime.Unix(), extraParams.Width, extraParams.Height)))
|
||||||
|
|
||||||
|
if avifAbsolutePath != expectedAvifPath {
|
||||||
|
t.Errorf("Avif absolute path is incorrect. Expected: %s, Got: %s", expectedAvifPath, avifAbsolutePath)
|
||||||
|
}
|
||||||
|
if webpAbsolutePath != expectedWebpPath {
|
||||||
|
t.Errorf("Webp absolute path is incorrect. Expected: %s, Got: %s", expectedWebpPath, webpAbsolutePath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenEtag(t *testing.T) {
|
func TestGenEtag(t *testing.T) {
|
||||||
@ -142,19 +200,23 @@ func TestGetRemoteImageInfo(t *testing.T) {
|
|||||||
func TestFetchRemoteImage(t *testing.T) {
|
func TestFetchRemoteImage(t *testing.T) {
|
||||||
// test the normal one
|
// test the normal one
|
||||||
fp := filepath.Join("./exhaust", "test.ico")
|
fp := filepath.Join("./exhaust", "test.ico")
|
||||||
url := "http://github.com/favicon.ico"
|
|
||||||
err := fetchRemoteImage(fp, url)
|
err := fetchRemoteImage(fp, "http://github.com/favicon.ico")
|
||||||
assert.Equal(t, err, nil)
|
assert.Equal(t, err, nil)
|
||||||
data, _ := os.ReadFile(fp)
|
data, _ := os.ReadFile(fp)
|
||||||
assert.Equal(t, "image/vnd.microsoft.icon", getFileContentType(data))
|
assert.Equal(t, "image/vnd.microsoft.icon", getFileContentType(data))
|
||||||
|
|
||||||
// test can't create file
|
// test can't create file
|
||||||
err = fetchRemoteImage("/", url)
|
err = fetchRemoteImage("/", "http://github.com/favicon.ico")
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
// test bad url
|
// test bad url
|
||||||
err = fetchRemoteImage(fp, "http://ahjdsgdsghja.cya")
|
err = fetchRemoteImage(fp, "http://ahjdsgdsghja.cya")
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
|
// test when returned is not image
|
||||||
|
err = fetchRemoteImage(fp, "https://github.com/")
|
||||||
|
assert.Equal(t, err.Error(), "remote file https://github.com/ is not image, remote returned text/html; charset=utf-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCleanProxyCache(t *testing.T) {
|
func TestCleanProxyCache(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user