Move request limiter to middleware.

This commit is contained in:
2025-07-09 17:00:39 +08:00
parent 0021a73951
commit b568b234c4
11 changed files with 73 additions and 71 deletions

View File

@@ -3,11 +3,9 @@ package service
import (
"nysoure/server/dao"
"nysoure/server/model"
"nysoure/server/utils"
"regexp"
"strconv"
"strings"
"time"
"github.com/gofiber/fiber/v3/log"
)
@@ -19,10 +17,6 @@ const (
maxCommentBriefLength = 256 // Maximum length of a comment brief
)
var (
commentsLimiter = utils.NewRequestLimiter(maxCommentsPerIP, 24*time.Hour)
)
type CommentRequest struct {
Content string `json:"content"` // markdown
// Images []uint `json:"images"` // Unrequired after new design
@@ -62,11 +56,6 @@ func findImagesInContent(content string, host string) []uint {
}
func CreateComment(req CommentRequest, userID uint, refID uint, ip string, cType model.CommentType, host string) (*model.CommentView, error) {
if !commentsLimiter.AllowRequest(ip) {
log.Warnf("IP %s has exceeded the comment limit of %d comments per day", ip, maxCommentsPerIP)
return nil, model.NewRequestError("Too many comments from this IP address, please try again later")
}
if len(req.Content) == 0 {
return nil, model.NewRequestError("Content cannot be empty")
}

View File

@@ -13,7 +13,6 @@ import (
"os"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/gofiber/fiber/v3/log"
@@ -25,23 +24,6 @@ const (
storageKeyUnavailable = "storage_key_unavailable" // Placeholder for unavailable storage key
)
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")
}
@@ -405,7 +387,7 @@ func GetFile(fid string) (*model.FileView, error) {
}
// DownloadFile handles the file download request. Return a presigned URL or a direct file path.
func DownloadFile(ip, fid, cfToken string) (string, string, error) {
func DownloadFile(fid, cfToken string) (string, string, error) {
passed, err := verifyCfToken(cfToken)
if err != nil {
log.Error("failed to verify cf token: ", err)
@@ -415,17 +397,6 @@ func DownloadFile(ip, fid, cfToken string) (string, string, error) {
log.Info("cf token verification failed")
return "", "", model.NewRequestError("cf token verification failed")
}
log.Info("File download request from: " + ip)
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)
if err != nil {
log.Error("failed to get file: ", err)

View File

@@ -3,7 +3,6 @@ package service
import (
"bytes"
"errors"
"github.com/disintegration/imaging"
"image"
"math"
"net/http"
@@ -14,14 +13,17 @@ import (
"strconv"
"time"
"github.com/disintegration/imaging"
"github.com/gofiber/fiber/v3/log"
"github.com/google/uuid"
_ "golang.org/x/image/bmp"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
_ "golang.org/x/image/bmp"
_ "golang.org/x/image/webp"
"github.com/chai2010/webp"
@@ -54,24 +56,12 @@ func init() {
}()
}
var (
imageLimiter = utils.NewRequestLimiter(maxUploadsPerIP, 24*time.Hour)
)
const maxUploadsPerIP = 100
func CreateImage(uid uint, ip string, data []byte) (uint, error) {
canUpload, err := checkUserCanUpload(uid)
if err != nil {
log.Error("Error checking user upload permission:", err)
return 0, model.NewInternalServerError("Error checking user upload permission")
}
if !canUpload {
// For a normal user, check the IP upload limit
if !imageLimiter.AllowRequest(ip) {
return 0, model.NewUnAuthorizedError("You have reached the maximum upload limit")
}
}
if len(data) == 0 {
return 0, model.NewRequestError("Image data is empty")

View File

@@ -3,7 +3,6 @@ package service
import (
"errors"
"fmt"
"github.com/gofiber/fiber/v3/log"
"nysoure/server/config"
"nysoure/server/dao"
"nysoure/server/model"
@@ -15,6 +14,8 @@ import (
"time"
"unicode"
"github.com/gofiber/fiber/v3/log"
"golang.org/x/crypto/bcrypt"
)
@@ -376,7 +377,7 @@ func validateUsername(username string) error {
if usernameLen < 3 || usernameLen > 20 {
return model.NewRequestError("Username must be between 3 and 20 characters")
}
for _, r := range []rune(username) {
for _, r := range username {
if r == ' ' || r == '\n' || r == '\r' || r == '\t' || r == '\v' || r == '\f' {
return model.NewRequestError("Username cannot contain whitespace characters")
}