mirror of
https://github.com/woodchen-ink/webp_server_go.git
synced 2025-07-18 05:32:02 +08:00
feat(handler, schedule): improve error handling and logging for file downloads and cleanup
This commit is contained in:
parent
8b6defa69c
commit
8381e24fc4
@ -34,20 +34,26 @@ func cleanProxyCache(cacheImagePath string) {
|
|||||||
func downloadFile(filepath string, url string) error {
|
func downloadFile(filepath string, url string) error {
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("下载文件时连接到远程错误!")
|
log.Errorf("下载文件时连接到远程错误!上游链接: %s, 错误: %v", url, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != fiber.StatusOK {
|
if resp.StatusCode != fiber.StatusOK {
|
||||||
log.Errorf("获取远程图像时远程返回 %s", resp.Status)
|
log.Errorf("获取远程图像失败。上游链接: %s, 状态码: %s", url, resp.Status)
|
||||||
return fmt.Errorf("意外的状态: %s", 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)
|
out, err := os.Create(filepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("创建目标文件失败。文件路径: %s, 错误: %v", filepath, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer out.Close()
|
defer out.Close()
|
||||||
@ -56,26 +62,33 @@ func downloadFile(filepath string, url string) error {
|
|||||||
buf := make([]byte, 32*1024)
|
buf := make([]byte, 32*1024)
|
||||||
_, err = io.CopyBuffer(out, resp.Body, buf)
|
_, err = io.CopyBuffer(out, resp.Body, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("写入文件失败。文件路径: %s, 上游链接: %s, 错误: %v", filepath, url, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Infof("文件下载成功。上游链接: %s, 保存路径: %s", url, filepath)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchRemoteImg(url string, subdir string) config.MetaFile {
|
func fetchRemoteImg(url, subdir string) (string, bool, error) {
|
||||||
var metadata config.MetaFile
|
log.Infof("正在获取远程图像: %s", url)
|
||||||
|
|
||||||
metadata = helper.ReadMetadata(url, "", subdir)
|
fileName := helper.HashString(url)
|
||||||
localRawImagePath := path.Join(config.Config.RemoteRawPath, subdir, metadata.Id)
|
localRawImagePath := path.Join(config.Config.RemoteRawPath, subdir, fileName)
|
||||||
|
|
||||||
if !helper.ImageExists(localRawImagePath) {
|
if helper.FileExists(localRawImagePath) {
|
||||||
log.Info("在远程原始文件中找不到远程文件,正在获取...")
|
log.Infof("远程图像已存在于本地: %s", localRawImagePath)
|
||||||
downloadFile(localRawImagePath, url)
|
return localRawImagePath, false, nil
|
||||||
// 重新读取更新后的元数据
|
|
||||||
metadata = helper.WriteMetadata(url, "", subdir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
func pingURL(url string) (string, int64, time.Time) {
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"webp_server_go/config"
|
"webp_server_go/config"
|
||||||
"webp_server_go/encoder"
|
"webp_server_go/encoder"
|
||||||
"webp_server_go/helper"
|
"webp_server_go/helper"
|
||||||
|
"webp_server_go/schedule"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@ -76,16 +77,33 @@ func Convert(c *fiber.Ctx) error {
|
|||||||
// 文件不在 EXHAUST_PATH 中,需要处理
|
// 文件不在 EXHAUST_PATH 中,需要处理
|
||||||
isLocalPath := strings.HasPrefix(matchedTarget, "./") || strings.HasPrefix(matchedTarget, "/")
|
isLocalPath := strings.HasPrefix(matchedTarget, "./") || strings.HasPrefix(matchedTarget, "/")
|
||||||
var rawImageAbs string
|
var rawImageAbs string
|
||||||
|
var isNewDownload bool
|
||||||
|
|
||||||
if isLocalPath {
|
if isLocalPath {
|
||||||
// 处理本地路径
|
// 处理本地路径
|
||||||
localPath := strings.TrimPrefix(reqURI, matchedPrefix)
|
localPath := strings.TrimPrefix(reqURI, matchedPrefix)
|
||||||
rawImageAbs = path.Join(matchedTarget, localPath)
|
rawImageAbs = path.Join(matchedTarget, localPath)
|
||||||
|
|
||||||
|
// 检查本地文件是否存在
|
||||||
|
if !helper.FileExists(rawImageAbs) {
|
||||||
|
log.Errorf("本地文件不存在: %s", rawImageAbs)
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
isNewDownload = false // 本地文件不需要清理
|
||||||
} else {
|
} else {
|
||||||
// 处理远程URL
|
// 处理远程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)
|
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)
|
return c.SendStatus(fiber.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果是新下载的远程文件,安排清理任务
|
||||||
|
if !isLocalPath && isNewDownload {
|
||||||
|
go schedule.ScheduleCleanup(rawImageAbs)
|
||||||
|
}
|
||||||
|
|
||||||
return c.SendFile(exhaustFilename)
|
return c.SendFile(exhaustFilename)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"webp_server_go/config"
|
"webp_server_go/config"
|
||||||
"webp_server_go/encoder"
|
"webp_server_go/encoder"
|
||||||
"webp_server_go/handler"
|
"webp_server_go/handler"
|
||||||
|
|
||||||
schedule "webp_server_go/schedule"
|
schedule "webp_server_go/schedule"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user