feat(handler/router): add image file type checking and non-image file handling

This commit is contained in:
wood chen 2024-10-23 06:53:00 +08:00
parent 11d6f95787
commit ffa5242983
2 changed files with 75 additions and 23 deletions

View File

@ -5,6 +5,7 @@ import (
"net/url"
"os"
"path"
"slices"
"strconv"
"strings"
"webp_server_go/config"
@ -22,12 +23,32 @@ func Convert(c *fiber.Ctx) error {
return c.SendString("Welcome to CZL WebP Server")
}
// 解析请求 URI 和查询参数
reqURI, reqURIwithQuery := parseRequestURI(c)
extraParams := parseExtraParams(c)
var (
reqURIRaw, _ = url.QueryUnescape(c.Path())
reqURIwithQueryRaw, _ = url.QueryUnescape(c.OriginalURL())
reqURI = path.Clean(reqURIRaw)
reqURIwithQuery = path.Clean(reqURIwithQueryRaw)
filename = path.Base(reqURI)
)
log.Debugf("Incoming connection from %s %s", c.IP(), reqURIwithQuery)
// 首先检查是否为图片文件
if !isImageFile(filename) {
log.Infof("Non-image file requested: %s", reqURI)
return handleNonImageFile(c, reqURI)
}
// 检查文件类型是否允许
if !helper.CheckAllowedType(filename) {
msg := "File extension not allowed! " + filename
log.Warn(msg)
return c.Status(fiber.StatusBadRequest).SendString(msg)
}
// 解析额外参数
extraParams := parseExtraParams(c)
// 检查路径是否匹配 IMG_MAP 中的任何前缀
matchedPrefix, matchedTarget := findMatchingPrefix(reqURI)
if matchedPrefix == "" {
@ -53,6 +74,48 @@ func Convert(c *fiber.Ctx) error {
}
}
func handleNonImageFile(c *fiber.Ctx, reqURI string) error {
var redirectURL string
for prefix, target := range config.Config.ImageMap {
if strings.HasPrefix(reqURI, prefix) {
if strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://") {
redirectURL = target + strings.TrimPrefix(reqURI, prefix)
} else {
return c.SendFile(path.Join(target, strings.TrimPrefix(reqURI, prefix)))
}
break
}
}
if redirectURL == "" {
localPath := path.Join(config.Config.ImgPath, reqURI)
if helper.FileExists(localPath) {
return c.SendFile(localPath)
} else {
return c.SendStatus(fiber.StatusNotFound)
}
}
log.Infof("Redirecting to: %s", redirectURL)
return c.Redirect(redirectURL, fiber.StatusFound)
}
func isImageFile(filename string) bool {
ext := strings.ToLower(path.Ext(filename))
if ext == "" {
return false
}
ext = ext[1:] // 移除开头的点
allowedTypes := config.Config.AllowedTypes
if len(allowedTypes) == 1 && allowedTypes[0] == "*" {
allowedTypes = config.NewWebPConfig().AllowedTypes
}
return slices.Contains(allowedTypes, ext)
}
func parseRequestURI(c *fiber.Ctx) (string, string) {
reqURIRaw, _ := url.QueryUnescape(c.Path())
reqURIwithQueryRaw, _ := url.QueryUnescape(c.OriginalURL())
@ -95,12 +158,7 @@ func handleLocalImage(c *fiber.Ctx, matchedTarget, reqURI, exhaustFilename strin
rawImageAbs := path.Join(matchedTarget, reqURI)
if !helper.FileExists(rawImageAbs) {
return c.Status(fiber.StatusNotFound).SendString("文件不存在")
}
if !helper.IsAllowedImageFile(path.Base(reqURI)) {
log.Infof("不允许的文件类型或非图片文件: %s", reqURI)
return c.SendFile(rawImageAbs)
return c.Status(fiber.StatusNotFound).SendString("本地文件不存在")
}
return processAndSaveImage(c, rawImageAbs, exhaustFilename, extraParams)
@ -115,12 +173,6 @@ func handleRemoteImage(c *fiber.Ctx, matchedTarget, matchedPrefix, reqURIwithQue
realRemoteAddr := buildRealRemoteAddr(targetUrl, matchedPrefix, reqURIwithQuery)
// 首先检查是否为允许的图片文件
if !helper.IsAllowedImageFile(path.Base(reqURIwithQuery)) {
log.Infof("不允许的文件类型或非图片文件: %s", reqURIwithQuery)
return c.Redirect(realRemoteAddr, 302)
}
rawImageAbs, isNewDownload, err := fetchRemoteImg(realRemoteAddr, targetUrl.Host)
if err != nil {
log.Errorf("获取远程图像失败: %v", err)

View File

@ -85,14 +85,14 @@ func ImageExists(filename string) bool {
return !info.IsDir()
}
// func CheckAllowedType(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)
// }
func CheckAllowedType(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)
}
func GenOptimizedAbsPath(metadata config.MetaFile, subdir string) (string, string, string) {
webpFilename := fmt.Sprintf("%s.webp", metadata.Id)