mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 13:42:02 +08:00
CI and minor fixes
* use GitHub Actions as CI * bump versions * Makefile and Dockerfile improvements * upgrade logrus
This commit is contained in:
parent
7c65d5e213
commit
67d40b4397
9
.dockerignore
Normal file
9
.dockerignore
Normal file
@ -0,0 +1,9 @@
|
||||
.github/*
|
||||
exhaust/*
|
||||
pics/*
|
||||
remote-raw/*
|
||||
scripts/*
|
||||
.git/*
|
||||
README.md
|
||||
LICENSE
|
||||
Makefile
|
21
.github/workflows/CI.yaml
vendored
Normal file
21
.github/workflows/CI.yaml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.3
|
||||
|
||||
- name: run test cases
|
||||
run: sudo apt install libaom-dev && make test && make
|
||||
|
@ -1,8 +1,8 @@
|
||||
FROM golang:alpine as builder
|
||||
FROM golang:1.17.4-alpine as builder
|
||||
|
||||
ARG IMG_PATH=/opt/pics
|
||||
ARG EXHAUST_PATH=/opt/exhaust
|
||||
RUN apk update && apk add alpine-sdk && mkdir /build
|
||||
RUN apk update && apk add alpine-sdk aom-dev && mkdir /build
|
||||
COPY go.mod /build
|
||||
RUN cd /build && go mod download
|
||||
|
||||
@ -10,7 +10,7 @@ COPY . /build
|
||||
RUN cd /build && sed -i "s|.\/pics|${IMG_PATH}|g" config.json \
|
||||
&& sed -i "s|\"\"|\"${EXHAUST_PATH}\"|g" config.json \
|
||||
&& sed -i 's/127.0.0.1/0.0.0.0/g' config.json \
|
||||
&& make docker
|
||||
&& go build -ldflags="-s -w" -o webp-server .
|
||||
|
||||
|
||||
|
||||
|
3
Makefile
3
Makefile
@ -14,6 +14,7 @@ default:
|
||||
make clean
|
||||
go build -o builds/webp-server-$(OS)-$(ARCH) .
|
||||
ls builds
|
||||
|
||||
all:
|
||||
make clean
|
||||
./scripts/build.sh $(OS) $(ARCH)
|
||||
@ -26,4 +27,4 @@ clean:
|
||||
rm -rf prefetch
|
||||
|
||||
docker:
|
||||
go build -ldflags="-s -w" -o webp-server .
|
||||
DOCKER_BUILDKIT=1 docker build -t webpsh/webps .
|
@ -21,7 +21,7 @@ var (
|
||||
prefetch, proxyMode bool
|
||||
remoteRaw = "remote-raw"
|
||||
config Config
|
||||
version = "0.3.2"
|
||||
version = "0.4.0"
|
||||
releaseUrl = "https://github.com/webp-sh/webp_server_go/releases/latest/download/"
|
||||
)
|
||||
|
||||
|
@ -81,8 +81,7 @@ func readRawImage(imgPath string, maxPixel int) (img image.Image, err error) {
|
||||
} else if strings.Contains(contentType, "bmp") {
|
||||
img, err = bmp.Decode(bytes.NewReader(data))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err != nil || img == nil {
|
||||
errinfo := fmt.Sprintf("image file %s is corrupted: %v", imgPath, err)
|
||||
log.Errorln(errinfo)
|
||||
return nil, errors.New(errinfo)
|
||||
|
@ -4,64 +4,63 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func walker() []string {
|
||||
var list []string
|
||||
_ = filepath.Walk("./pics", func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
list = append(list, path)
|
||||
_ = filepath.Walk("./pics", func(p string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() && !strings.HasPrefix(path.Base(p), ".") {
|
||||
list = append(list, p)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
func TestWebpEncoder(t *testing.T) {
|
||||
var webp = "/tmp/test-result.webp"
|
||||
func TestWebPEncoder(t *testing.T) {
|
||||
// Go through every files
|
||||
var dest = "/tmp/test-result"
|
||||
var target = walker()
|
||||
|
||||
for _, f := range target {
|
||||
//fmt.Println(b, c, webp)
|
||||
runEncoder(t, f, webp)
|
||||
runEncoder(t, f, dest)
|
||||
}
|
||||
_ = os.Remove(dest)
|
||||
}
|
||||
_ = os.Remove(webp)
|
||||
|
||||
// test error
|
||||
err := webpEncoder("./pics/empty.jpg", webp, 80)
|
||||
assert.NotNil(t, err)
|
||||
_ = os.Remove(webp)
|
||||
func TestAvifEncoder(t *testing.T) {
|
||||
// Only one file: img_over_16383px.jpg might cause memory issues on CI environment
|
||||
var dest = "/tmp/test-result"
|
||||
avifEncoder("./pics/big.jpg", dest, 80)
|
||||
assertType(t, dest, "image/avif")
|
||||
}
|
||||
|
||||
func TestNonExistImage(t *testing.T) {
|
||||
var webp = "/tmp/test-result.webp"
|
||||
// test error
|
||||
var err = webpEncoder("./pics/empty.jpg", webp, 80)
|
||||
assert.NotNil(t, err)
|
||||
_ = os.Remove(webp)
|
||||
var dest = "/tmp/test-result"
|
||||
webpEncoder("./pics/empty.jpg", dest, 80)
|
||||
avifEncoder("./pics/empty.jpg", dest, 80)
|
||||
}
|
||||
|
||||
func TestConvertFail(t *testing.T) {
|
||||
var webp = "/tmp/test-result.webp"
|
||||
var err = webpEncoder("./pics/webp_server.jpg", webp, -1)
|
||||
assert.NotNil(t, t, err)
|
||||
var dest = "/tmp/test-result"
|
||||
webpEncoder("./pics/webp_server.jpg", dest, -1)
|
||||
avifEncoder("./pics/webp_server.jpg", dest, -1)
|
||||
}
|
||||
|
||||
func runEncoder(t *testing.T, file string, webp string) {
|
||||
//t.Logf("convert from %s to %s", file, webp)
|
||||
var err = webpEncoder(file, webp, 80)
|
||||
if file == "pics/empty.jpg" && err != nil {
|
||||
func runEncoder(t *testing.T, file string, dest string) {
|
||||
if file == "pics/empty.jpg" {
|
||||
t.Log("Empty file, that's okay.")
|
||||
} else if err != nil {
|
||||
t.Fatalf("Fatal, convert failed for %s: %v ", file, err)
|
||||
}
|
||||
webpEncoder(file, dest, 80)
|
||||
assertType(t, dest, "image/webp")
|
||||
|
||||
}
|
||||
|
||||
data, _ := ioutil.ReadFile(webp)
|
||||
func assertType(t *testing.T, dest, mime string) {
|
||||
data, _ := ioutil.ReadFile(dest)
|
||||
types := getFileContentType(data[:512])
|
||||
if types != "image/webp" {
|
||||
t.Fatal("Fatal, file type is wrong!")
|
||||
}
|
||||
|
||||
assert.Equalf(t, mime, types, "File %s should be %s", dest, mime)
|
||||
}
|
||||
|
4
go.mod
4
go.mod
@ -7,12 +7,14 @@ require (
|
||||
github.com/chai2010/webp v1.1.0
|
||||
github.com/gofiber/fiber/v2 v2.4.0
|
||||
github.com/h2non/filetype v1.1.3
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
|
||||
github.com/schollz/progressbar/v3 v3.8.3
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/staktrace/go-update v0.0.0-20210525161054-fc019945f9a2
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/valyala/fasthttp v1.18.0
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1
|
||||
golang.org/x/sys v0.0.0-20211204120058-94396e421777 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
|
5
go.sum
5
go.sum
@ -25,6 +25,8 @@ github.com/schollz/progressbar/v3 v3.8.3 h1:FnLGl3ewlDUP+YdSwveXBaXs053Mem/du+wr
|
||||
github.com/schollz/progressbar/v3 v3.8.3/go.mod h1:pWnVCjSBZsT2X3nx9HfRdnCDrpbevliMeoEVhStwHko=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/staktrace/go-update v0.0.0-20210525161054-fc019945f9a2 h1:kyTDvRL8TyTHOx0aK1PKMPVfkI7rCLDC1nrKF7SYOBc=
|
||||
github.com/staktrace/go-update v0.0.0-20210525161054-fc019945f9a2/go.mod h1:yzHsbjWRHVF1vVGsluwqCc2TvogFSx9C8TeBh34cMb0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@ -53,6 +55,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201210223839-7e3030f88018/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -60,6 +63,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg=
|
||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211204120058-94396e421777 h1:QAkhGVjOxMa+n4mlsAWeAU+BMZmimQAaNiMu+iUi94E=
|
||||
golang.org/x/sys v0.0.0-20211204120058-94396e421777/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
153
helper_test.go
153
helper_test.go
@ -1,31 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/valyala/fasthttp"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// test this file: go test -v -cover .
|
||||
// test all files: go test -v -cover .
|
||||
// test one case: go test -v -run TestSelectFormat
|
||||
|
||||
func TestGetFileContentType(t *testing.T) {
|
||||
var data = []byte("hello")
|
||||
var expected = "text/plain; charset=utf-8"
|
||||
var data = []byte("remember remember the 5th of november")
|
||||
var expected = ""
|
||||
var result = getFileContentType(data)
|
||||
|
||||
assert.Equalf(t, result, expected, "Result: [%s], Expected: [%s]", result, expected)
|
||||
|
||||
}
|
||||
|
||||
func TestFileCount(t *testing.T) {
|
||||
var data = ".github"
|
||||
var expected = 2
|
||||
var data = "scripts"
|
||||
var expected int64 = 2
|
||||
var result = fileCount(data)
|
||||
assert.Equalf(t, result, expected, "Result: [%d], Expected: [%d]", result, expected)
|
||||
|
||||
}
|
||||
|
||||
func TestImageExists(t *testing.T) {
|
||||
@ -71,108 +73,63 @@ func TestGenEtag(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestGoOrigin(t *testing.T) {
|
||||
func TestSelectFormat(t *testing.T) {
|
||||
// this is a complete test case for webp compatibility
|
||||
// func goOrigin(header, ua string) bool
|
||||
// UNLESS YOU KNOW WHAT YOU ARE DOING, DO NOT CHANGE THE TEST CASE MAPPING HERE.
|
||||
var testCase = map[[2]string]bool{
|
||||
var fullSupport = []string{"avif", "webp", "raw"}
|
||||
var webpSupport = []string{"webp", "raw"}
|
||||
var jpegSupport = []string{"raw"}
|
||||
var testCase = map[[2]string][]string{
|
||||
// Latest Chrome on Windows, macOS, linux, Android and iOS 13
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"}: fullSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"}: fullSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36"}: fullSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.60 Mobile Safari/537.36"}: fullSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Mozilla/5.0 (Linux; Android 6.0; HTC M8t) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.74 Mobile Safari/537.36"}: fullSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "HTCM8t_LTE/1.0 Android/4.4 release/2013 Browser/WAP2.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 AppleWebKit/534.30"}: webpSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/83.0.4103.63 Mobile/15E148 Safari/604.1"}: jpegSupport,
|
||||
|
||||
// macOS Catalina Safari
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15"}: true,
|
||||
// macOS Chrome
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.88 Safari/537.36"}: false,
|
||||
// iOS14 Safari
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1"}: false,
|
||||
// iOS14 Chrome
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1"}: false,
|
||||
// iPadOS 14 Safari
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1"}: false,
|
||||
// iPadOS 14 Chrome
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1"}: false,
|
||||
// Warning: these three are real capture headers - I don't have iOS/iPadOS prior to version 14
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "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"}: true,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPad; CPU OS 10_15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/25.0 Mobile/15E148 Safari/605.1.15"}: true,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/83.0.4103.63 Mobile/15E148 Safari/604.1"}: true,
|
||||
}
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15"}: jpegSupport,
|
||||
|
||||
for value, is := range testCase {
|
||||
assert.Equalf(t, is, goOrigin(value[0], value[1]), "[%v]:[%s]", value, is)
|
||||
}
|
||||
}
|
||||
// iOS14 Safari and Chrome
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1"}: webpSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1"}: webpSupport,
|
||||
|
||||
func TestUaOrigin(t *testing.T) {
|
||||
// reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox
|
||||
// https://developer.chrome.com/multidevice/user-agent#chrome_for_ios_user_agent
|
||||
// iPadOS 14 Safari and Chrome
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1"}: webpSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1"}: webpSupport,
|
||||
|
||||
// UNLESS YOU KNOW WHAT YOU ARE DOING, DO NOT CHANGE THE TEST CASE MAPPING HERE.
|
||||
var testCase = map[string]bool{
|
||||
// Chrome on Windows, macOS, linux, iOS and Android
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36": false,
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36": false,
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36": false,
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/83.0.4103.63 Mobile/15E148 Safari/604.1": true,
|
||||
"Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.60 Mobile Safari/537.36": false,
|
||||
|
||||
// Firefox on Windows, macOS, linux, iOS and Android
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0": false,
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:76.0) Gecko/20100101 Firefox/76.0": false,
|
||||
"Mozilla/5.0 (X11; Linux i686; rv:76.0) Gecko/20100101 Firefox/76.0": false,
|
||||
"Mozilla/5.0 (iPad; CPU OS 10_15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/25.0 Mobile/15E148 Safari/605.1.15": true,
|
||||
"Mozilla/5.0 (Android 10; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0": false,
|
||||
|
||||
// Safari on macOS and iOS
|
||||
"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": true,
|
||||
"Mozilla/5.0 (iPad; CPU OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1": true,
|
||||
|
||||
// WeChat on iOS, Windows, and Android
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 wxwork/2.1.5 MicroMessenger/6.3.22": true,
|
||||
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.691.400 QQBrowser/9.0.2524.400": false,
|
||||
"Mozilla/5.0 (Linux; Android 7.0; LG-H831 Build/NRD90U; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.91 Mobile Safari/537.36 MicroMessenger/6.6.7.1303(0x26060743) NetType/WIFI Language/zh_TW": false,
|
||||
// iOS 15 Safari, Firefox and Chrome
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.1"}: webpSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/39.0 Mobile/15E148 Safari/605.1.15"}: webpSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/96.0.4664.53 Mobile/15E148 Safari/604.1"}: webpSupport,
|
||||
|
||||
// IE
|
||||
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko": true,
|
||||
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)": true,
|
||||
|
||||
[2]string{"application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko"}: jpegSupport,
|
||||
// Others
|
||||
"PostmanRuntime/7.26.1": true,
|
||||
"curl/7.64.1": true,
|
||||
[2]string{"", "PostmanRuntime/7.26.1"}: jpegSupport,
|
||||
[2]string{"", "curl/7.64.1"}: jpegSupport,
|
||||
[2]string{"image/webp", "curl/7.64.1"}: webpSupport,
|
||||
[2]string{"image/avif,image/webp", "curl/7.64.1"}: fullSupport,
|
||||
|
||||
// these four are captured from iOS14/iPadOS14, which supports webp
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1": false,
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1\n": false,
|
||||
"Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1": false,
|
||||
"Mozilla/5.0 (iPad; CPU OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1": false,
|
||||
// some weird browsers
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Mozilla/5.0 (iPhone; CPU iPhone OS 15_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.16(0x18001033) NetType/WIFI Language/zh_CN"}: webpSupport,
|
||||
[2]string{"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Mozilla/5.0 (Linux; Android 6.0; HTC M8t Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/45.0.2454.95 Mobile Safari/537.36 MMWEBID/4285 MicroMessenger/8.0.15.2001(0x28000F41) Process/tools WeChat/arm32 Weixin GPVersion/1 NetType/WIFI Language/zh_CN ABI/arm32"}: webpSupport,
|
||||
}
|
||||
for browser, expected := range testCase {
|
||||
var header fasthttp.RequestHeader
|
||||
header.Set("accept", browser[0])
|
||||
header.Set("user-agent", browser[1])
|
||||
guessed := guessSupportedFormat(&header)
|
||||
|
||||
sort.Strings(expected)
|
||||
sort.Strings(guessed)
|
||||
log.Infof("%s expected%s --- actual %s", browser, expected, guessed)
|
||||
assert.Equal(t, expected, guessed)
|
||||
}
|
||||
|
||||
for browser, is := range testCase {
|
||||
assert.Equalf(t, is, uaOrigin(browser), "[%v]:[%s]", is, browser)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestHeaderOrigin(t *testing.T) {
|
||||
// Chrome: Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8
|
||||
// Safari 版本14.0.1 (15610.2.11.51.10, 15610): Accept: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
|
||||
// Safari Technology Preview Release 116 (Safari 14.1, WebKit 15611.1.5.3) Accept: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
|
||||
|
||||
// UNLESS YOU KNOW WHAT YOU ARE DOING, DO NOT CHANGE THE TEST CASE MAPPING HERE.
|
||||
var testCase = map[string]bool{
|
||||
"image/avif,image/webp,image/apng,image/*,*/*;q=0.8": false,
|
||||
"*/*": true,
|
||||
"image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5": true,
|
||||
"I don't know what it is:-)": true,
|
||||
}
|
||||
for header, is := range testCase {
|
||||
assert.Equalf(t, is, headerOrigin(header), "[%v]:[%s]", is, header)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChanErr(t *testing.T) {
|
||||
var value = 2
|
||||
var testC = make(chan int, 2)
|
||||
testC <- value
|
||||
chanErr(testC)
|
||||
value = <-testC
|
||||
assert.Equal(t, 2, value)
|
||||
}
|
||||
|
||||
func TestGetRemoteImageInfo(t *testing.T) {
|
||||
@ -197,7 +154,7 @@ func TestFetchRemoteImage(t *testing.T) {
|
||||
err := fetchRemoteImage(fp, url)
|
||||
assert.Equal(t, err, nil)
|
||||
data, _ := ioutil.ReadFile(fp)
|
||||
assert.Equal(t, "image/x-icon", getFileContentType(data))
|
||||
assert.Equal(t, "image/vnd.microsoft.icon", getFileContentType(data))
|
||||
|
||||
// test can't create file
|
||||
err = fetchRemoteImage("/", url)
|
||||
|
@ -35,6 +35,7 @@ func prefetchImages(confImgPath string, ExhaustPath string) {
|
||||
proposedURI := strings.Replace(picAbsPath, confImgPath, "", 1)
|
||||
avif, webp := genOptimizedAbs(picAbsPath, ExhaustPath, info.Name(), proposedURI)
|
||||
_ = os.MkdirAll(path.Dir(avif), 0755)
|
||||
log.Infof("Prefetching %s", picAbsPath)
|
||||
go convertFilter(picAbsPath, avif, webp, finishChan)
|
||||
_ = bar.Add(<-finishChan)
|
||||
return nil
|
||||
|
@ -11,24 +11,15 @@ import (
|
||||
)
|
||||
|
||||
func TestPrefetchImages(t *testing.T) {
|
||||
// single thread
|
||||
fp := "./prefetch"
|
||||
_ = os.Mkdir(fp, 0755)
|
||||
prefetchImages("./pics", "./prefetch", "80")
|
||||
prefetchImages("./pics/dir1/", "./prefetch")
|
||||
count := fileCount("./prefetch")
|
||||
assert.Equal(t, 8, count)
|
||||
_ = os.RemoveAll(fp)
|
||||
|
||||
// concurrency
|
||||
jobs = 2
|
||||
_ = os.Mkdir(fp, 0755)
|
||||
prefetchImages("./pics", "./prefetch", "80")
|
||||
count = fileCount("./prefetch")
|
||||
assert.Equal(t, 6, count)
|
||||
assert.Equal(t, int64(2), count)
|
||||
_ = os.RemoveAll(fp)
|
||||
}
|
||||
|
||||
func TestBadPrefetch(t *testing.T) {
|
||||
jobs = 1
|
||||
prefetchImages("./pics2", "./prefetch", "80")
|
||||
prefetchImages("./pics2", "./prefetch")
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ import (
|
||||
|
||||
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"
|
||||
acceptWebP = "image/webp,image/apng,image/*,*/*;q=0.8"
|
||||
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"
|
||||
)
|
||||
|
||||
@ -29,10 +31,14 @@ func setupParam() {
|
||||
remoteRaw = "remote-raw"
|
||||
}
|
||||
|
||||
func requestToServer(url string, app *fiber.App, ua string) (*http.Response, []byte) {
|
||||
func requestToServer(url string, app *fiber.App, ua, accept string) (*http.Response, []byte) {
|
||||
req := httptest.NewRequest("GET", url, nil)
|
||||
req.Header.Set("User-Agent", ua)
|
||||
resp, _ := app.Test(req, 60000)
|
||||
req.Header.Set("Accept", accept)
|
||||
resp, err := app.Test(req, 120000)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
data, _ := ioutil.ReadAll(resp.Body)
|
||||
return resp, data
|
||||
}
|
||||
@ -44,7 +50,7 @@ func TestServerHeaders(t *testing.T) {
|
||||
url := "http://127.0.0.1:3333/webp_server.bmp"
|
||||
|
||||
// test for chrome
|
||||
response, _ := requestToServer(url, app, chromeUA)
|
||||
response, _ := requestToServer(url, app, chromeUA, acceptWebP)
|
||||
ratio := response.Header.Get("X-Compression-Rate")
|
||||
etag := response.Header.Get("Etag")
|
||||
|
||||
@ -52,7 +58,7 @@ func TestServerHeaders(t *testing.T) {
|
||||
assert.NotEqual(t, "", etag)
|
||||
|
||||
// test for safari
|
||||
response, _ = requestToServer(url, app, safariUA)
|
||||
response, _ = requestToServer(url, app, safariUA, acceptLegacy)
|
||||
ratio = response.Header.Get("X-Compression-Rate")
|
||||
etag = response.Header.Get("Etag")
|
||||
|
||||
@ -66,9 +72,9 @@ func TestConvert(t *testing.T) {
|
||||
"http://127.0.0.1:3333/webp_server.jpg": "image/webp",
|
||||
"http://127.0.0.1:3333/webp_server.bmp": "image/webp",
|
||||
"http://127.0.0.1:3333/webp_server.png": "image/webp",
|
||||
"http://127.0.0.1:3333/empty.jpg": "text/plain; charset=utf-8",
|
||||
"http://127.0.0.1:3333/empty.jpg": "",
|
||||
"http://127.0.0.1:3333/png.jpg": "image/webp",
|
||||
"http://127.0.0.1:3333/12314.jpg": "text/plain; charset=utf-8",
|
||||
"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/%e5%a4%aa%e7%a5%9e%e5%95%a6.png": "image/webp",
|
||||
"http://127.0.0.1:3333/太神啦.png": "image/webp",
|
||||
@ -78,9 +84,9 @@ func TestConvert(t *testing.T) {
|
||||
"http://127.0.0.1:3333/webp_server.jpg": "image/jpeg",
|
||||
"http://127.0.0.1:3333/webp_server.bmp": "image/bmp",
|
||||
"http://127.0.0.1:3333/webp_server.png": "image/png",
|
||||
"http://127.0.0.1:3333/empty.jpg": "text/plain; charset=utf-8",
|
||||
"http://127.0.0.1:3333/empty.jpg": "",
|
||||
"http://127.0.0.1:3333/png.jpg": "image/png",
|
||||
"http://127.0.0.1:3333/12314.jpg": "text/plain; charset=utf-8",
|
||||
"http://127.0.0.1:3333/12314.jpg": "",
|
||||
"http://127.0.0.1:3333/dir1/inside.jpg": "image/jpeg",
|
||||
}
|
||||
|
||||
@ -89,14 +95,14 @@ func TestConvert(t *testing.T) {
|
||||
|
||||
// test Chrome
|
||||
for url, respType := range testChromeLink {
|
||||
_, data := requestToServer(url, app, chromeUA)
|
||||
_, data := requestToServer(url, app, chromeUA, acceptWebP)
|
||||
contentType := getFileContentType(data)
|
||||
assert.Equal(t, respType, contentType)
|
||||
}
|
||||
|
||||
// test Safari
|
||||
for url, respType := range testSafariLink {
|
||||
_, data := requestToServer(url, app, safariUA)
|
||||
_, data := requestToServer(url, app, safariUA, acceptLegacy)
|
||||
contentType := getFileContentType(data)
|
||||
assert.Equal(t, respType, contentType)
|
||||
}
|
||||
@ -112,13 +118,13 @@ func TestConvertNotAllowed(t *testing.T) {
|
||||
|
||||
// not allowed, but we have the file
|
||||
url := "http://127.0.0.1:3333/webp_server.bmp"
|
||||
_, data := requestToServer(url, app, chromeUA)
|
||||
_, data := requestToServer(url, app, chromeUA, acceptWebP)
|
||||
contentType := getFileContentType(data)
|
||||
assert.Equal(t, "image/bmp", contentType)
|
||||
|
||||
// not allowed, random file
|
||||
url = url + "hagdgd"
|
||||
_, data = requestToServer(url, app, chromeUA)
|
||||
_, data = requestToServer(url, app, chromeUA, acceptWebP)
|
||||
assert.Contains(t, string(data), "File extension not allowed")
|
||||
|
||||
}
|
||||
@ -132,7 +138,7 @@ func TestConvertProxyModeBad(t *testing.T) {
|
||||
|
||||
// this is local random image, should be 500
|
||||
url := "http://127.0.0.1:3333/webp_8888server.bmp"
|
||||
resp, _ := requestToServer(url, app, chromeUA)
|
||||
resp, _ := requestToServer(url, app, chromeUA, acceptWebP)
|
||||
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
|
||||
|
||||
}
|
||||
@ -147,29 +153,26 @@ func TestConvertProxyModeWork(t *testing.T) {
|
||||
config.ImgPath = "https://webp.sh"
|
||||
url := "https://webp.sh/images/cover.jpg"
|
||||
|
||||
resp, data := requestToServer(url, app, chromeUA)
|
||||
resp, data := requestToServer(url, app, chromeUA, acceptWebP)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(t, "image/webp", getFileContentType(data))
|
||||
|
||||
// test proxyMode with Safari
|
||||
resp, data = requestToServer(url, app, safariUA)
|
||||
resp, data = requestToServer(url, app, safariUA, acceptLegacy)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(t, "image/jpeg", getFileContentType(data))
|
||||
}
|
||||
|
||||
func TestConvertBigger(t *testing.T) {
|
||||
setupParam()
|
||||
config.Quality = "100"
|
||||
|
||||
jpg, _ := ioutil.ReadFile("pics/big.jpg")
|
||||
config.Quality = 100
|
||||
|
||||
var app = fiber.New()
|
||||
app.Get("/*", convert)
|
||||
|
||||
url := "http://127.0.0.1:3333/big.jpg"
|
||||
response, data := requestToServer(url, app, chromeUA)
|
||||
response, data := requestToServer(url, app, chromeUA, acceptWebP)
|
||||
assert.Equal(t, "image/jpeg", response.Header.Get("content-type"))
|
||||
assert.True(t, len(data) == len(jpg))
|
||||
|
||||
assert.Equal(t, "image/jpeg", getFileContentType(data))
|
||||
_ = os.RemoveAll(config.ExhaustPath)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ func Test404AutoUpdate(t *testing.T) {
|
||||
dir := "./update"
|
||||
releaseUrl = releaseUrl + "a"
|
||||
autoUpdate()
|
||||
assert.Equal(t, 0, fileCount(dir))
|
||||
assert.Equal(t, int64(0), fileCount(dir))
|
||||
_ = os.RemoveAll(dir)
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ func TestLoadConfig(t *testing.T) {
|
||||
assert.Equal(t, "./exhaust", c.ExhaustPath)
|
||||
assert.Equal(t, "127.0.0.1", c.Host)
|
||||
assert.Equal(t, "3333", c.Port)
|
||||
assert.Equal(t, "80", c.Quality)
|
||||
assert.Equal(t, float32(80), c.Quality)
|
||||
assert.Equal(t, "./pics", c.ImgPath)
|
||||
assert.Equal(t, []string{"jpg", "png", "jpeg", "bmp"}, c.AllowedTypes)
|
||||
}
|
||||
@ -43,7 +43,7 @@ func TestMainFunction(t *testing.T) {
|
||||
|
||||
// run main function
|
||||
go main()
|
||||
time.Sleep(time.Second * 2)
|
||||
time.Sleep(time.Second * 5)
|
||||
// verbose, prefetch
|
||||
assert.Equal(t, log.GetLevel(), log.DebugLevel)
|
||||
assert.True(t, verboseMode)
|
||||
|
Loading…
x
Reference in New Issue
Block a user