Add download limit.

This commit is contained in:
2025-05-14 22:06:22 +08:00
parent 5c08ab34ea
commit 4b986ffd86
2 changed files with 35 additions and 3 deletions

View File

@@ -74,3 +74,7 @@ func MaxFileSize() int64 {
func AllowRegister() bool { func AllowRegister() bool {
return config.AllowRegister return config.AllowRegister
} }
func MaxDownloadsPerDayForSingleIP() int {
return config.MaxDownloadsPerDayForSingleIP
}

View File

@@ -9,6 +9,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"sync"
"time" "time"
"github.com/gofiber/fiber/v3/log" "github.com/gofiber/fiber/v3/log"
@@ -19,7 +20,24 @@ const (
blockSize = 4 * 1024 * 1024 // 4MB blockSize = 4 * 1024 * 1024 // 4MB
) )
func getUploadingSize(uid uint) int64 { var (
ipDownloads = sync.Map{}
)
func init() {
go func() {
for {
// Clean up old IP download records every 24 hours
time.Sleep(24 * time.Hour)
ipDownloads.Range(func(key, value interface{}) bool {
ipDownloads.Delete(key)
return true
})
}
}()
}
func getUploadingSize() int64 {
return dao.GetStatistic("uploading_size") return dao.GetStatistic("uploading_size")
} }
@@ -84,7 +102,7 @@ func CreateUploadingFile(uid uint, filename string, description string, fileSize
return nil, model.NewRequestError("file size exceeds the limit") return nil, model.NewRequestError("file size exceeds the limit")
} }
currentUploadingSize := getUploadingSize(uid) currentUploadingSize := getUploadingSize()
if currentUploadingSize+fileSize > config.MaxUploadingSize() { if currentUploadingSize+fileSize > config.MaxUploadingSize() {
log.Info("A new uploading file is rejected due to max uploading size limit") log.Info("A new uploading file is rejected due to max uploading size limit")
return nil, model.NewRequestError("server is busy, please try again later") return nil, model.NewRequestError("server is busy, please try again later")
@@ -367,7 +385,17 @@ func GetFile(fid string) (*model.FileView, error) {
return file.ToView(), nil return file.ToView(), nil
} }
func DownloadFile(fid string) (string, string, error) { func DownloadFile(ip string, fid string) (string, string, error) {
downloads, _ := ipDownloads.Load(ip)
if downloads == nil {
ipDownloads.Store(ip, 1)
} else {
count := downloads.(int)
if count >= config.MaxDownloadsPerDayForSingleIP() {
return "", "", model.NewRequestError("Too many requests, please try again later")
}
ipDownloads.Store(ip, count+1)
}
file, err := dao.GetFile(fid) file, err := dao.GetFile(fid)
if err != nil { if err != nil {
log.Error("failed to get file: ", err) log.Error("failed to get file: ", err)