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"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"webp_server_go/config"
|
"webp_server_go/config"
|
||||||
@ -22,12 +23,32 @@ func Convert(c *fiber.Ctx) error {
|
|||||||
return c.SendString("Welcome to CZL WebP Server")
|
return c.SendString("Welcome to CZL WebP Server")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析请求 URI 和查询参数
|
var (
|
||||||
reqURI, reqURIwithQuery := parseRequestURI(c)
|
reqURIRaw, _ = url.QueryUnescape(c.Path())
|
||||||
extraParams := parseExtraParams(c)
|
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)
|
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 中的任何前缀
|
// 检查路径是否匹配 IMG_MAP 中的任何前缀
|
||||||
matchedPrefix, matchedTarget := findMatchingPrefix(reqURI)
|
matchedPrefix, matchedTarget := findMatchingPrefix(reqURI)
|
||||||
if matchedPrefix == "" {
|
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) {
|
func parseRequestURI(c *fiber.Ctx) (string, string) {
|
||||||
reqURIRaw, _ := url.QueryUnescape(c.Path())
|
reqURIRaw, _ := url.QueryUnescape(c.Path())
|
||||||
reqURIwithQueryRaw, _ := url.QueryUnescape(c.OriginalURL())
|
reqURIwithQueryRaw, _ := url.QueryUnescape(c.OriginalURL())
|
||||||
@ -95,12 +158,7 @@ func handleLocalImage(c *fiber.Ctx, matchedTarget, reqURI, exhaustFilename strin
|
|||||||
rawImageAbs := path.Join(matchedTarget, reqURI)
|
rawImageAbs := path.Join(matchedTarget, reqURI)
|
||||||
|
|
||||||
if !helper.FileExists(rawImageAbs) {
|
if !helper.FileExists(rawImageAbs) {
|
||||||
return c.Status(fiber.StatusNotFound).SendString("文件不存在")
|
return c.Status(fiber.StatusNotFound).SendString("本地文件不存在")
|
||||||
}
|
|
||||||
|
|
||||||
if !helper.IsAllowedImageFile(path.Base(reqURI)) {
|
|
||||||
log.Infof("不允许的文件类型或非图片文件: %s", reqURI)
|
|
||||||
return c.SendFile(rawImageAbs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return processAndSaveImage(c, rawImageAbs, exhaustFilename, extraParams)
|
return processAndSaveImage(c, rawImageAbs, exhaustFilename, extraParams)
|
||||||
@ -115,12 +173,6 @@ func handleRemoteImage(c *fiber.Ctx, matchedTarget, matchedPrefix, reqURIwithQue
|
|||||||
|
|
||||||
realRemoteAddr := buildRealRemoteAddr(targetUrl, matchedPrefix, reqURIwithQuery)
|
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)
|
rawImageAbs, isNewDownload, err := fetchRemoteImg(realRemoteAddr, targetUrl.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("获取远程图像失败: %v", err)
|
log.Errorf("获取远程图像失败: %v", err)
|
||||||
|
@ -85,14 +85,14 @@ func ImageExists(filename string) bool {
|
|||||||
return !info.IsDir()
|
return !info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
// func CheckAllowedType(imgFilename string) bool {
|
func CheckAllowedType(imgFilename string) bool {
|
||||||
// if config.Config.AllowedTypes[0] == "*" {
|
if config.Config.AllowedTypes[0] == "*" {
|
||||||
// return true
|
return true
|
||||||
// }
|
}
|
||||||
// imgFilenameExtension := strings.ToLower(path.Ext(imgFilename))
|
imgFilenameExtension := strings.ToLower(path.Ext(imgFilename))
|
||||||
// imgFilenameExtension = strings.TrimPrefix(imgFilenameExtension, ".") // .jpg -> jpg
|
imgFilenameExtension = strings.TrimPrefix(imgFilenameExtension, ".") // .jpg -> jpg
|
||||||
// return slices.Contains(config.Config.AllowedTypes, imgFilenameExtension)
|
return slices.Contains(config.Config.AllowedTypes, imgFilenameExtension)
|
||||||
// }
|
}
|
||||||
|
|
||||||
func GenOptimizedAbsPath(metadata config.MetaFile, subdir string) (string, string, string) {
|
func GenOptimizedAbsPath(metadata config.MetaFile, subdir string) (string, string, string) {
|
||||||
webpFilename := fmt.Sprintf("%s.webp", metadata.Id)
|
webpFilename := fmt.Sprintf("%s.webp", metadata.Id)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user