mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 05:32:02 +08:00
feat(handler/router): add image file type checking and non-image file handling
This commit is contained in:
parent
11d6f95787
commit
ffa5242983
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user