Skip to content

Commit

Permalink
render webp on brower without support for heic
Browse files Browse the repository at this point in the history
  • Loading branch information
n0vad3v committed Dec 1, 2024
1 parent f102014 commit 88308ad
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 35 deletions.
9 changes: 8 additions & 1 deletion handler/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ func Convert(c *fiber.Ctx) error {
if supportedFormats["raw"] == true &&
supportedFormats["webp"] == false &&
supportedFormats["avif"] == false &&
supportedFormats["jxl"] == false {
supportedFormats["jxl"] == false &&
supportedFormats["heic"] == false {
dest := path.Join(config.Config.ExhaustPath, targetHostName, metadata.Id)
if !helper.ImageExists(dest) {
encoder.ResizeItself(rawImageAbs, dest, extraParams)
Expand Down Expand Up @@ -184,6 +185,12 @@ func Convert(c *fiber.Ctx) error {
if supportedFormats["jxl"] {
availableFiles = append(availableFiles, jxlAbs)
}
// If raw format is not supported(e,g: heic), remove it from the list
// Because we shouldn't serve the heic format if it's not supported
if !supportedFormats["heic"] && helper.GetImageExtension(rawImageAbs) == "heic" {
// Remove the "raw" from the list
availableFiles = availableFiles[1:]
}

finalFilename := helper.FindSmallestFiles(availableFiles)
contentType := helper.GetFileContentType(finalFilename)
Expand Down
3 changes: 2 additions & 1 deletion handler/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func setupParam() {
// setup parameters here...
config.Config.ImgPath = "../pics"
config.Config.ExhaustPath = "../exhaust_test"
config.Config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp"}
config.Config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp", "heic"}
config.Config.MetadataPath = "../metadata"
config.Config.RemoteRawPath = "../remote-raw"
config.ProxyMode = false
Expand Down Expand Up @@ -128,6 +128,7 @@ func TestConvert(t *testing.T) {
"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",
"http://127.0.0.1:3333/sample3.heic": "image/webp", // webp because browser does not support heic
}

var testChromeAvifLink = map[string]string{
Expand Down
55 changes: 23 additions & 32 deletions helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,21 @@ func ImageExists(filename string) bool {
return !info.IsDir()
}

func GetImageExtension(filename string) string {
return strings.TrimPrefix(strings.ToLower(path.Ext(filename)), ".")
}

// CheckAllowedExtension checks if the image extension is in the user's allowed types
func CheckAllowedExtension(imgFilename string) bool {
if config.Config.AllowedTypes[0] == "*" {
return true
}
imgFilenameExtension := strings.ToLower(path.Ext(imgFilename))
imgFilenameExtension = strings.TrimPrefix(imgFilenameExtension, ".") // .jpg -> jpg
return slices.Contains(config.Config.AllowedTypes, imgFilenameExtension)
return slices.Contains(config.Config.AllowedTypes, GetImageExtension(imgFilename))
}

// CheckImageExtension checks if the image extension is in the WebP Server Go's default types
func CheckImageExtension(imgFilename string) bool {
imgFilenameExtension := strings.ToLower(path.Ext(imgFilename))
imgFilenameExtension = strings.TrimPrefix(imgFilenameExtension, ".") // .jpg -> jpg
return slices.Contains(config.DefaultAllowedTypes, imgFilenameExtension)
return slices.Contains(config.DefaultAllowedTypes, GetImageExtension(imgFilename))
}

func GenOptimizedAbsPath(metadata config.MetaFile, subdir string) (string, string, string) {
Expand Down Expand Up @@ -134,6 +134,7 @@ func GuessSupportedFormat(header *fasthttp.RequestHeader) map[string]bool {
"webp": false,
"avif": false,
"jxl": false,
"heic": false,
}

ua = string(header.Peek("user-agent"))
Expand All @@ -149,26 +150,29 @@ func GuessSupportedFormat(header *fasthttp.RequestHeader) map[string]bool {
if strings.Contains(accept, "image/jxl") {
supported["jxl"] = true
}
parsedUA := useragent.Parse(ua)

supportedWebPs := []string{"iPhone OS 14", "CPU OS 14", "iPhone OS 15", "CPU OS 15", "iPhone OS 16", "CPU OS 16", "iPhone OS 17", "CPU OS 17", "iPhone OS 18", "CPU OS 18"}
for _, version := range supportedWebPs {
if strings.Contains(ua, version) {
supported["webp"] = true
break
}
if parsedUA.IsIOS() && parsedUA.VersionNo.Major >= 14 {
supported["webp"] = true
}

supportedAVIFs := []string{"iPhone OS 16", "CPU OS 16", "iPhone OS 17", "CPU OS 17", "iPhone OS 18", "CPU OS 18"}
for _, version := range supportedAVIFs {
if strings.Contains(ua, version) {
supported["avif"] = true
break
}
if parsedUA.IsIOS() && parsedUA.VersionNo.Major >= 16 {
supported["avif"] = true
}

// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15 <- iPad
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Safari/605.1.15 <- Mac
// Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1 <- iPhone @ Safari
if parsedUA.IsIOS() && parsedUA.VersionNo.Major >= 17 {
supported["jxl"] = true
}

if parsedUA.IsSafari() && parsedUA.VersionNo.Major >= 17 {
supported["heic"] = true
}

// Firefox will not send correct accept header on url without image extension, we need to check user agent to see if `Firefox/133` version is supported
// https://caniuse.com/webp
parsedUA := useragent.Parse(ua)
if parsedUA.IsFirefox() && parsedUA.VersionNo.Major >= 133 {
supported["webp"] = true
}
Expand All @@ -178,19 +182,6 @@ func GuessSupportedFormat(header *fasthttp.RequestHeader) map[string]bool {
supported["avif"] = true
}

// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15 <- iPad
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Safari/605.1.15 <- Mac
// Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1 <- iPhone @ Safari
supportedJXLs := []string{"iPhone OS 17", "CPU OS 17", "Version/17", "iPhone OS 18", "CPU OS 18", "Version/18"}
if strings.Contains(ua, "iPhone") || strings.Contains(ua, "Macintosh") {
for _, version := range supportedJXLs {
if strings.Contains(ua, version) {
supported["jxl"] = true
break
}
}
}

return supported
}

Expand Down
13 changes: 12 additions & 1 deletion helper/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,25 @@ func TestGuessSupportedFormat(t *testing.T) {
"jxl": true,
},
},
{
name: "WebP Supported",
userAgent: "iPhone OS 15",
accept: "image/webp, image/png",
expected: map[string]bool{
"raw": true,
"webp": true,
"avif": false,
"jxl": false,
},
},
{
name: "WebP/AVIF Supported",
userAgent: "iPhone OS 16",
accept: "image/webp, image/png",
expected: map[string]bool{
"raw": true,
"webp": true,
"avif": true,
"avif": false,
"jxl": false,
},
},
Expand Down
Binary file added pics/sample3.heic
Binary file not shown.

0 comments on commit 88308ad

Please sign in to comment.