feat(handler, schedule): improve error handling and logging for file downloads and cleanup

This commit is contained in:
wood chen 2024-10-22 23:52:57 +08:00
parent 8b6defa69c
commit 8381e24fc4
5 changed files with 68 additions and 17 deletions

3
go.work Normal file
View File

@ -0,0 +1,3 @@
go 1.23.1
use .

View File

@ -34,20 +34,26 @@ func cleanProxyCache(cacheImagePath string) {
func downloadFile(filepath string, url string) error {
resp, err := http.Get(url)
if err != nil {
log.Errorln("下载文件时连接到远程错误!")
log.Errorf("下载文件时连接到远程错误!上游链接: %s, 错误: %v", url, err)
return err
}
defer resp.Body.Close()
if resp.StatusCode != fiber.StatusOK {
log.Errorf("获取远程图像时远程返回 %s", resp.Status)
return fmt.Errorf("意外的状态: %s", resp.Status)
log.Errorf("获取远程图像失败。上游链接: %s, 状态码: %s", url, resp.Status)
return fmt.Errorf("意外的状态: %s, 上游链接: %s", resp.Status, url)
}
// 创建目标文件
_ = os.MkdirAll(path.Dir(filepath), 0755)
err = os.MkdirAll(path.Dir(filepath), 0755)
if err != nil {
log.Errorf("创建目标目录失败。路径: %s, 错误: %v", path.Dir(filepath), err)
return err
}
out, err := os.Create(filepath)
if err != nil {
log.Errorf("创建目标文件失败。文件路径: %s, 错误: %v", filepath, err)
return err
}
defer out.Close()
@ -56,26 +62,33 @@ func downloadFile(filepath string, url string) error {
buf := make([]byte, 32*1024)
_, err = io.CopyBuffer(out, resp.Body, buf)
if err != nil {
log.Errorf("写入文件失败。文件路径: %s, 上游链接: %s, 错误: %v", filepath, url, err)
return err
}
log.Infof("文件下载成功。上游链接: %s, 保存路径: %s", url, filepath)
return nil
}
func fetchRemoteImg(url string, subdir string) config.MetaFile {
var metadata config.MetaFile
func fetchRemoteImg(url, subdir string) (string, bool, error) {
log.Infof("正在获取远程图像: %s", url)
metadata = helper.ReadMetadata(url, "", subdir)
localRawImagePath := path.Join(config.Config.RemoteRawPath, subdir, metadata.Id)
fileName := helper.HashString(url)
localRawImagePath := path.Join(config.Config.RemoteRawPath, subdir, fileName)
if !helper.ImageExists(localRawImagePath) {
log.Info("在远程原始文件中找不到远程文件,正在获取...")
downloadFile(localRawImagePath, url)
// 重新读取更新后的元数据
metadata = helper.WriteMetadata(url, "", subdir)
if helper.FileExists(localRawImagePath) {
log.Infof("远程图像已存在于本地: %s", localRawImagePath)
return localRawImagePath, false, nil
}
return metadata
err := downloadFile(localRawImagePath, url)
if err != nil {
log.Errorf("下载远程图像失败: %v", err)
return "", false, err
}
log.Infof("成功获取远程图像: %s", localRawImagePath)
return localRawImagePath, true, nil
}
func pingURL(url string) (string, int64, time.Time) {

View File

@ -9,6 +9,7 @@ import (
"webp_server_go/config"
"webp_server_go/encoder"
"webp_server_go/helper"
"webp_server_go/schedule"
"github.com/gofiber/fiber/v2"
log "github.com/sirupsen/logrus"
@ -76,16 +77,33 @@ func Convert(c *fiber.Ctx) error {
// 文件不在 EXHAUST_PATH 中,需要处理
isLocalPath := strings.HasPrefix(matchedTarget, "./") || strings.HasPrefix(matchedTarget, "/")
var rawImageAbs string
var isNewDownload bool
if isLocalPath {
// 处理本地路径
localPath := strings.TrimPrefix(reqURI, matchedPrefix)
rawImageAbs = path.Join(matchedTarget, localPath)
// 检查本地文件是否存在
if !helper.FileExists(rawImageAbs) {
log.Errorf("本地文件不存在: %s", rawImageAbs)
return c.SendStatus(fiber.StatusNotFound)
}
isNewDownload = false // 本地文件不需要清理
} else {
// 处理远程URL
targetUrl, _ := url.Parse(matchedTarget)
targetUrl, err := url.Parse(matchedTarget)
if err != nil {
log.Errorf("解析目标 URL 失败: %v", err)
return c.SendStatus(fiber.StatusInternalServerError)
}
remoteAddr := targetUrl.Scheme + "://" + targetUrl.Host + strings.Replace(reqURI, matchedPrefix, targetUrl.Path, 1)
metadata := fetchRemoteImg(remoteAddr, targetUrl.Host)
rawImageAbs = path.Join(config.Config.RemoteRawPath, targetUrl.Host, metadata.Id)
rawImageAbs, isNewDownload, err = fetchRemoteImg(remoteAddr, targetUrl.Host)
if err != nil {
log.Errorf("获取远程图像失败: %v", err)
return c.SendStatus(fiber.StatusInternalServerError)
}
}
// 检查是否为允许的图片文件
@ -117,6 +135,10 @@ func Convert(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusInternalServerError)
}
}
// 如果是新下载的远程文件,安排清理任务
if !isLocalPath && isNewDownload {
go schedule.ScheduleCleanup(rawImageAbs)
}
return c.SendFile(exhaustFilename)
}

View File

@ -111,3 +111,15 @@ func CleanCache() {
}
}
var cleanupDelay = 5 * time.Minute
func ScheduleCleanup(filePath string) {
time.AfterFunc(cleanupDelay, func() {
if err := os.Remove(filePath); err != nil {
log.Warnf("清理原始文件失败: %s, 错误: %v", filePath, err)
} else {
log.Infof("成功清理原始文件: %s", filePath)
}
})
}

View File

@ -9,6 +9,7 @@ import (
"webp_server_go/config"
"webp_server_go/encoder"
"webp_server_go/handler"
schedule "webp_server_go/schedule"
"github.com/gofiber/fiber/v2"