fix
This commit is contained in:
@@ -160,8 +160,6 @@ ocr:
|
|||||||
ratelimit:
|
ratelimit:
|
||||||
requests: 5000
|
requests: 5000
|
||||||
window: 60s
|
window: 60s
|
||||||
exclude_domains: # 排除频率限制的域名
|
|
||||||
- "api.*" # 排除所有 api.* 二级域名(业务核心接口)
|
|
||||||
|
|
||||||
# 每日请求限制配置
|
# 每日请求限制配置
|
||||||
daily_ratelimit:
|
daily_ratelimit:
|
||||||
|
|||||||
@@ -117,11 +117,9 @@ type JWTConfig struct {
|
|||||||
|
|
||||||
// RateLimitConfig 限流配置
|
// RateLimitConfig 限流配置
|
||||||
type RateLimitConfig struct {
|
type RateLimitConfig struct {
|
||||||
Requests int `mapstructure:"requests"`
|
Requests int `mapstructure:"requests"`
|
||||||
Window time.Duration `mapstructure:"window"`
|
Window time.Duration `mapstructure:"window"`
|
||||||
Burst int `mapstructure:"burst"`
|
Burst int `mapstructure:"burst"`
|
||||||
ExcludePaths []string `mapstructure:"exclude_paths"` // 排除频率限制的路径
|
|
||||||
ExcludeDomains []string `mapstructure:"exclude_domains"` // 排除频率限制的域名
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DailyRateLimitConfig 每日限流配置
|
// DailyRateLimitConfig 每日限流配置
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -43,23 +42,6 @@ func (m *RateLimitMiddleware) GetPriority() int {
|
|||||||
// Handle 返回中间件处理函数
|
// Handle 返回中间件处理函数
|
||||||
func (m *RateLimitMiddleware) Handle() gin.HandlerFunc {
|
func (m *RateLimitMiddleware) Handle() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
// 检查是否在排除域名中
|
|
||||||
host := c.Request.Host
|
|
||||||
// 移除端口部分
|
|
||||||
if idx := strings.Index(host, ":"); idx != -1 {
|
|
||||||
host = host[:idx]
|
|
||||||
}
|
|
||||||
if m.isExcludedDomain(host) {
|
|
||||||
c.Next()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否在排除路径中
|
|
||||||
if m.isExcludedPath(c.Request.URL.Path) {
|
|
||||||
c.Next()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取客户端标识(IP地址)
|
// 获取客户端标识(IP地址)
|
||||||
clientID := m.getClientID(c)
|
clientID := m.getClientID(c)
|
||||||
|
|
||||||
@@ -168,64 +150,6 @@ func (m *RateLimitMiddleware) cleanup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isExcludedDomain 检查域名是否在排除列表中
|
|
||||||
func (m *RateLimitMiddleware) isExcludedDomain(host string) bool {
|
|
||||||
for _, excludeDomain := range m.config.RateLimit.ExcludeDomains {
|
|
||||||
// 支持通配符匹配
|
|
||||||
if strings.HasPrefix(excludeDomain, "*") {
|
|
||||||
// 后缀匹配,如 "*.api.example.com" 匹配 "api.example.com"
|
|
||||||
if strings.HasSuffix(host, excludeDomain[1:]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else if strings.HasSuffix(excludeDomain, "*") {
|
|
||||||
// 前缀匹配,如 "api.*" 匹配 "api.example.com"
|
|
||||||
if strings.HasPrefix(host, excludeDomain[:len(excludeDomain)-1]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 精确匹配
|
|
||||||
if host == excludeDomain {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// isExcludedPath 检查路径是否在排除列表中
|
|
||||||
func (m *RateLimitMiddleware) isExcludedPath(path string) bool {
|
|
||||||
for _, excludePath := range m.config.RateLimit.ExcludePaths {
|
|
||||||
// 支持多种匹配模式
|
|
||||||
if strings.HasPrefix(excludePath, "*") {
|
|
||||||
// 前缀匹配,如 "*api_name" 匹配 "/api/v1/any_api_name"
|
|
||||||
if strings.Contains(path, excludePath[1:]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else if strings.HasSuffix(excludePath, "*") {
|
|
||||||
// 后缀匹配,如 "/api/v1/*" 匹配 "/api/v1/any_api_name"
|
|
||||||
if strings.HasPrefix(path, excludePath[:len(excludePath)-1]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
} else if strings.Contains(excludePath, "*") {
|
|
||||||
// 中间通配符匹配,如 "/api/v1/*api_name" 匹配 "/api/v1/any_api_name"
|
|
||||||
parts := strings.Split(excludePath, "*")
|
|
||||||
if len(parts) == 2 {
|
|
||||||
prefix := parts[0]
|
|
||||||
suffix := parts[1]
|
|
||||||
if strings.HasPrefix(path, prefix) && strings.HasSuffix(path, suffix) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 精确匹配
|
|
||||||
if path == excludePath {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetStats 获取限流统计
|
// GetStats 获取限流统计
|
||||||
func (m *RateLimitMiddleware) GetStats() map[string]interface{} {
|
func (m *RateLimitMiddleware) GetStats() map[string]interface{} {
|
||||||
m.mutex.RLock()
|
m.mutex.RLock()
|
||||||
|
|||||||
Reference in New Issue
Block a user