mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 05:32:02 +08:00
iOS 14 support, bump to 0.3.1 (#63)
Use `accept` header first, then `user-agent` header. Add complete test case. This should resolve part of #61
This commit is contained in:
parent
9136beb307
commit
37d8d8ba13
@ -14,7 +14,8 @@ It will convert `jpg,jpeg,png` files by default, this can be customized by editi
|
||||
|
||||
> e.g When you visit `https://your.website/pics/tsuki.jpg`,it will serve as `image/webp` format without changing the URL.
|
||||
>
|
||||
> For Safari and Opera users, the original image will be used.
|
||||
> ~~For Safari and Opera users, the original image will be used.~~
|
||||
> We've now support Safari/Chrome/Firefox on iOS 14/iPadOS 14
|
||||
|
||||
|
||||
## Simple Usage Steps
|
||||
|
@ -21,7 +21,7 @@ var (
|
||||
prefetch, proxyMode bool
|
||||
|
||||
config Config
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
32
helper.go
32
helper.go
@ -143,13 +143,26 @@ func getCompressionRate(RawImagePath string, webpAbsPath string) string {
|
||||
return fmt.Sprintf(`%.2f`, compressionRate)
|
||||
}
|
||||
|
||||
func goOrigin(UA string) bool {
|
||||
func goOrigin(header, ua string) bool {
|
||||
// We'll first check accept headers, if accept headers is false, we'll then go to UA part
|
||||
if headerOrigin(header) && uaOrigin(ua) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func uaOrigin(ua string) bool {
|
||||
// iOS 14 and iPadOS 14 supports webp, the identification token is iPhone OS 14_2_1 and CPU OS 14_2
|
||||
// for more information, please check test case
|
||||
if strings.Contains(UA, "Firefox") || strings.Contains(UA, "Chrome") {
|
||||
if strings.Contains(ua, "iPhone OS 14") || strings.Contains(ua, "CPU OS 14") {
|
||||
// this is iOS 14/iPadOS 14
|
||||
return false
|
||||
} else if strings.Contains(ua, "Firefox") || strings.Contains(ua, "Chrome") {
|
||||
// Chrome or firefox on macOS Windows
|
||||
} else if strings.Contains(UA, "Android") || strings.Contains(UA, "Linux") {
|
||||
} else if strings.Contains(ua, "Android") || strings.Contains(ua, "Linux") {
|
||||
// on Android and Linux
|
||||
} else if strings.Contains(UA, "FxiOS") || strings.Contains(UA, "CriOS") {
|
||||
} else if strings.Contains(ua, "FxiOS") || strings.Contains(ua, "CriOS") {
|
||||
//firefox and Chrome on iOS
|
||||
return true
|
||||
} else {
|
||||
@ -157,3 +170,14 @@ func goOrigin(UA string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func headerOrigin(header string) bool {
|
||||
// Webkit is really weird especially on iOS, it doesn't even send out effective accept headers.
|
||||
// Head to test case if you want to know more
|
||||
if strings.Contains(header, "image/webp") {
|
||||
return false
|
||||
} else {
|
||||
// go to origin
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,38 @@ func TestGenEtag(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGoOrigin(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{
|
||||
// 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,
|
||||
}
|
||||
|
||||
for value, is := range testCase {
|
||||
assert.Equalf(t, is, goOrigin(value[0], value[1]), "[%v]:[%s]", value, is)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 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,
|
||||
@ -98,14 +127,37 @@ func TestGoOrigin(t *testing.T) {
|
||||
// Others
|
||||
"PostmanRuntime/7.26.1": true,
|
||||
"curl/7.64.1": true,
|
||||
|
||||
// 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,
|
||||
}
|
||||
|
||||
for browser, is := range testCase {
|
||||
assert.Equalf(t, is, goOrigin(browser), "[%v]:[%s]", is, browser)
|
||||
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)
|
||||
|
@ -19,12 +19,13 @@ func convert(c *fiber.Ctx) error {
|
||||
var rawImageAbs = path.Join(config.ImgPath, reqURI) // /home/xxx/mypic/123.jpg
|
||||
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")
|
||||
log.Debugf("Incoming connection from %s@%s with %s", UA, c.IP(), imgFilename)
|
||||
var ua = c.Get("User-Agent")
|
||||
var accept = c.Get("accept")
|
||||
log.Debugf("Incoming connection from %s@%s with %s", ua, c.IP(), imgFilename)
|
||||
|
||||
needOrigin := goOrigin(UA)
|
||||
needOrigin := goOrigin(accept, ua)
|
||||
if needOrigin {
|
||||
log.Infof("A Safari/IE/whatever user has arrived...%s", UA)
|
||||
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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
Name: webp-server
|
||||
Version: 0.3.0
|
||||
Version: 0.3.1
|
||||
Release: 1%{?dist}
|
||||
Summary: Go version of WebP Server. A tool that will serve your JPG/PNGs as WebP format with compression, on-the-fly.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user