mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 13:42:02 +08:00
Enable AVIF compression in proxy mode (#194)
* Enable AVIF compression in proxy mode * Fix AVIF in proxy mode PR after PR#192 merge * Bump version to 0.8.0
This commit is contained in:
parent
96802dc3bc
commit
ccc99e2e1c
@ -31,7 +31,7 @@ var (
|
|||||||
prefetch, proxyMode bool
|
prefetch, proxyMode bool
|
||||||
remoteRaw = "remote-raw"
|
remoteRaw = "remote-raw"
|
||||||
config Config
|
config Config
|
||||||
version = "0.7.0"
|
version = "0.8.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -33,7 +33,7 @@ func resizeImage(img *vips.ImageRef, extraParams ExtraParams) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertFilter(raw, avifPath, webpPath string, extraParams ExtraParams, c chan int) {
|
func convertFilter(raw, avifPath string, webpPath string, extraParams ExtraParams, c chan int) {
|
||||||
// all absolute paths
|
// all absolute paths
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
14
helper.go
14
helper.go
@ -11,7 +11,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/h2non/filetype"
|
"github.com/h2non/filetype"
|
||||||
|
|
||||||
@ -167,9 +166,6 @@ func genOptimizedAbsPath(rawImagePath string, exhaustPath string, imageName stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genEtag(ImgAbsPath string) string {
|
func genEtag(ImgAbsPath string) string {
|
||||||
if proxyMode {
|
|
||||||
ImgAbsPath = path.Join(remoteRaw, strings.Replace(ImgAbsPath, config.ImgPath, "", -1))
|
|
||||||
}
|
|
||||||
data, err := os.ReadFile(ImgAbsPath)
|
data, err := os.ReadFile(ImgAbsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
@ -228,16 +224,6 @@ func guessSupportedFormat(header *fasthttp.RequestHeader) []string {
|
|||||||
return accepted
|
return accepted
|
||||||
}
|
}
|
||||||
|
|
||||||
func chooseProxy(proxyRawSize string, optimizedAbs string) bool {
|
|
||||||
var proxyRaw, _ = strconv.Atoi(proxyRawSize)
|
|
||||||
webp, _ := os.ReadFile(optimizedAbs)
|
|
||||||
if len(webp) > proxyRaw {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func findSmallestFiles(files []string) string {
|
func findSmallestFiles(files []string) string {
|
||||||
// walk files
|
// walk files
|
||||||
var small int64
|
var small int64
|
||||||
|
@ -63,15 +63,6 @@ func TestGenEtag(t *testing.T) {
|
|||||||
var result = genEtag(data)
|
var result = genEtag(data)
|
||||||
|
|
||||||
assert.Equalf(t, result, expected, "Result: [%s], Expected: [%s]", result, expected)
|
assert.Equalf(t, result, expected, "Result: [%s], Expected: [%s]", result, expected)
|
||||||
|
|
||||||
// proxy mode
|
|
||||||
proxyMode = true
|
|
||||||
config.ImgPath = "https://github.com/webp-sh/webp_server_go/raw/master/"
|
|
||||||
remoteRaw = ""
|
|
||||||
data = "https://github.com/webp-sh/webp_server_go/raw/master/pics/webp_server.png"
|
|
||||||
result = genEtag(data)
|
|
||||||
assert.Equal(t, result, "W/\"269387-6FFD6D2D\"")
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectFormat(t *testing.T) {
|
func TestSelectFormat(t *testing.T) {
|
||||||
|
42
router.go
42
router.go
@ -5,7 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
|
// "os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -64,21 +65,11 @@ func convert(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
goodFormat := guessSupportedFormat(&c.Request().Header)
|
goodFormat := guessSupportedFormat(&c.Request().Header)
|
||||||
|
|
||||||
// old browser only, send the original image or fetch from remote and send.
|
if proxyMode {
|
||||||
if len(goodFormat) == 1 {
|
rawImageAbs, _ = proxyHandler(c, reqURIwithQuery)
|
||||||
c.Set("ETag", genEtag(rawImageAbs))
|
|
||||||
if proxyMode {
|
|
||||||
localRemoteTmpPath := remoteRaw + reqURI
|
|
||||||
_ = fetchRemoteImage(localRemoteTmpPath, rawImageAbs)
|
|
||||||
return c.SendFile(localRemoteTmpPath)
|
|
||||||
} else {
|
|
||||||
return c.SendFile(rawImageAbs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if proxyMode {
|
log.Debugf("rawImageAbs=%s", rawImageAbs)
|
||||||
return proxyHandler(c, reqURIwithQuery)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the original image for existence,
|
// Check the original image for existence,
|
||||||
if !imageExists(rawImageAbs) {
|
if !imageExists(rawImageAbs) {
|
||||||
@ -120,7 +111,7 @@ func convert(c *fiber.Ctx) error {
|
|||||||
return c.SendFile(finalFileName)
|
return c.SendFile(finalFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func proxyHandler(c *fiber.Ctx, reqURIwithQuery string) error {
|
func proxyHandler(c *fiber.Ctx, reqURIwithQuery string) (string, error) {
|
||||||
// https://test.webp.sh/mypic/123.jpg?someother=200&somebugs=200
|
// https://test.webp.sh/mypic/123.jpg?someother=200&somebugs=200
|
||||||
realRemoteAddr := config.ImgPath + reqURIwithQuery
|
realRemoteAddr := config.ImgPath + reqURIwithQuery
|
||||||
|
|
||||||
@ -130,25 +121,16 @@ func proxyHandler(c *fiber.Ctx, reqURIwithQuery string) error {
|
|||||||
localRawImagePath := remoteRaw + "/" + reqURIwithQueryHash // For store the remote raw image, /home/webp_server/remote-raw/378e740ca56144b7587f3af9debeee544842879a
|
localRawImagePath := remoteRaw + "/" + reqURIwithQueryHash // For store the remote raw image, /home/webp_server/remote-raw/378e740ca56144b7587f3af9debeee544842879a
|
||||||
// Ping Remote for status code and etag info
|
// Ping Remote for status code and etag info
|
||||||
log.Infof("Remote Addr is %s fetching", realRemoteAddr)
|
log.Infof("Remote Addr is %s fetching", realRemoteAddr)
|
||||||
statusCode, etagValue, remoteLength := getRemoteImageInfo(realRemoteAddr)
|
statusCode, _, _ := getRemoteImageInfo(realRemoteAddr)
|
||||||
localEtagWebPPath := config.ExhaustPath + "/" + reqURIwithQueryHash + "-etag-" + etagValue // For store the remote webp image, /home/webp_server/exhaust/378e740ca56144b7587f3af9debeee544842879a-etag-<etagValue>
|
|
||||||
|
|
||||||
if statusCode == 200 {
|
if statusCode == 200 {
|
||||||
if imageExists(localEtagWebPPath) {
|
if imageExists(localRawImagePath) {
|
||||||
chooseProxy(remoteLength, localEtagWebPPath)
|
return localRawImagePath, nil
|
||||||
return c.SendFile(localEtagWebPPath)
|
|
||||||
} else {
|
} else {
|
||||||
// Temporary store of remote file.
|
// Temporary store of remote file.
|
||||||
cleanProxyCache(config.ExhaustPath + reqURIwithQuery + "*")
|
cleanProxyCache(config.ExhaustPath + reqURIwithQuery + "*")
|
||||||
_ = fetchRemoteImage(localRawImagePath, realRemoteAddr)
|
err := fetchRemoteImage(localRawImagePath, realRemoteAddr)
|
||||||
_ = os.MkdirAll(path.Dir(localEtagWebPPath), 0755)
|
return localRawImagePath, err
|
||||||
encodeErr := webpEncoder(localRawImagePath, localEtagWebPPath, config.Quality, ExtraParams{Width: 0, Height: 0})
|
|
||||||
if encodeErr != nil {
|
|
||||||
// Send as it is.
|
|
||||||
return c.SendFile(localRawImagePath)
|
|
||||||
}
|
|
||||||
chooseProxy(remoteLength, localEtagWebPPath)
|
|
||||||
return c.SendFile(localEtagWebPPath)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msg := fmt.Sprintf("Remote returned %d status code!", statusCode)
|
msg := fmt.Sprintf("Remote returned %d status code!", statusCode)
|
||||||
@ -156,6 +138,6 @@ func proxyHandler(c *fiber.Ctx, reqURIwithQuery string) error {
|
|||||||
log.Warn(msg)
|
log.Warn(msg)
|
||||||
_ = c.SendStatus(statusCode)
|
_ = c.SendStatus(statusCode)
|
||||||
cleanProxyCache(config.ExhaustPath + reqURIwithQuery + "*")
|
cleanProxyCache(config.ExhaustPath + reqURIwithQuery + "*")
|
||||||
return errors.New(msg)
|
return "", errors.New(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
chromeUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36"
|
chromeUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36"
|
||||||
acceptWebP = "image/webp,image/apng,image/*,*/*;q=0.8"
|
acceptWebP = "image/webp,image/apng,image/*,*/*;q=0.8"
|
||||||
|
acceptAvif = "image/avif,image/*,*/*;q=0.8"
|
||||||
acceptLegacy = "image/jpeg"
|
acceptLegacy = "image/jpeg"
|
||||||
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"
|
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"
|
||||||
)
|
)
|
||||||
@ -76,7 +77,19 @@ func TestConvert(t *testing.T) {
|
|||||||
"http://127.0.0.1:3333/12314.jpg": "",
|
"http://127.0.0.1:3333/12314.jpg": "",
|
||||||
"http://127.0.0.1:3333/dir1/inside.jpg": "image/webp",
|
"http://127.0.0.1:3333/dir1/inside.jpg": "image/webp",
|
||||||
"http://127.0.0.1:3333/%e5%a4%aa%e7%a5%9e%e5%95%a6.png": "image/webp",
|
"http://127.0.0.1:3333/%e5%a4%aa%e7%a5%9e%e5%95%a6.png": "image/webp",
|
||||||
"http://127.0.0.1:3333/太神啦.png": "image/webp",
|
"http://127.0.0.1:3333/太神啦.png": "image/webp",
|
||||||
|
}
|
||||||
|
|
||||||
|
var testChromeAvifLink = map[string]string{
|
||||||
|
"http://127.0.0.1:3333/webp_server.jpg": "image/avif",
|
||||||
|
"http://127.0.0.1:3333/webp_server.bmp": "image/avif",
|
||||||
|
"http://127.0.0.1:3333/webp_server.png": "image/avif",
|
||||||
|
"http://127.0.0.1:3333/empty.jpg": "",
|
||||||
|
"http://127.0.0.1:3333/png.jpg": "image/avif",
|
||||||
|
"http://127.0.0.1:3333/12314.jpg": "",
|
||||||
|
"http://127.0.0.1:3333/dir1/inside.jpg": "image/avif",
|
||||||
|
"http://127.0.0.1:3333/%e5%a4%aa%e7%a5%9e%e5%95%a6.png": "image/avif",
|
||||||
|
"http://127.0.0.1:3333/太神啦.png": "image/avif",
|
||||||
}
|
}
|
||||||
|
|
||||||
var testSafariLink = map[string]string{
|
var testSafariLink = map[string]string{
|
||||||
@ -108,6 +121,15 @@ func TestConvert(t *testing.T) {
|
|||||||
assert.Equal(t, respType, contentType)
|
assert.Equal(t, respType, contentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test Avif is processed in proxy mode
|
||||||
|
config.EnableAVIF = true
|
||||||
|
for url, respType := range testChromeAvifLink {
|
||||||
|
resp, data := requestToServer(url, app, chromeUA, acceptAvif)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
contentType := getFileContentType(data)
|
||||||
|
assert.NotNil(t, respType)
|
||||||
|
assert.Equal(t, respType, contentType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConvertNotAllowed(t *testing.T) {
|
func TestConvertNotAllowed(t *testing.T) {
|
||||||
@ -138,11 +160,11 @@ func TestConvertProxyModeBad(t *testing.T) {
|
|||||||
var app = fiber.New()
|
var app = fiber.New()
|
||||||
app.Get("/*", convert)
|
app.Get("/*", convert)
|
||||||
|
|
||||||
// this is local random image, should be 500
|
// this is local random image, should be 404
|
||||||
url := "http://127.0.0.1:3333/webp_8888server.bmp"
|
url := "http://127.0.0.1:3333/webp_8888server.bmp"
|
||||||
resp, _ := requestToServer(url, app, chromeUA, acceptWebP)
|
resp, _ := requestToServer(url, app, chromeUA, acceptWebP)
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
|
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user