This commit is contained in:
toom1996
2026-09-29 19:59:30 +08:00
parent d15d2a4701
commit 361ffc01af
28 changed files with 896 additions and 47 deletions

View File

@ -22,6 +22,8 @@ type Config struct {
Upload UploadConfig `yaml:"upload"`
CORS CORSConfig `yaml:"cors"`
ClientSign ClientSignConfig `yaml:"client_sign"`
// RateLimit 按客户端 IP 的速率限制(兜底防刷,与 client_sign 配合)。
RateLimit RateLimitConfig `yaml:"rate_limit"`
// Ingest 爬虫上报接口的 HMAC 验签配置(服务端到服务端,密钥不下发前端)。
Ingest IngestConfig `yaml:"ingest"`
// S4 缤纷云对象存储配置(S3 兼容,爬虫入库图片上传目标)。
@ -171,6 +173,13 @@ type ClientSignConfig struct {
TTLSeconds int `yaml:"ttl_seconds"`
}
// RateLimitConfig 按客户端 IP 的速率限制配置(令牌桶)。
type RateLimitConfig struct {
Enabled bool `yaml:"enabled"`
RPS int `yaml:"rps"` // 每秒补充令牌数(平均允许 QPS)
Burst int `yaml:"burst"` // 突发容量(瞬间允许的最大请求数)
}
// defaultConfig 返回内置默认值,保证 yml 缺字段时服务仍可启动。
func defaultConfig() *Config {
return &Config{
@ -215,6 +224,11 @@ func defaultConfig() *Config {
Secret: "",
TTLSeconds: 30,
},
RateLimit: RateLimitConfig{
Enabled: false,
RPS: 20,
Burst: 40,
},
Ingest: IngestConfig{
Secret: "",
TTLSeconds: 300,
@ -332,6 +346,20 @@ func (c *Config) applyEnv() {
envStr("CLIENT_SIGN_SECRET", &c.ClientSign.Secret)
envInt("CLIENT_SIGN_TTL", &c.ClientSign.TTLSeconds)
// CORS 允许的来源(逗号分隔),覆盖 yml 的 allow_origins,便于容器注入具体域名收紧跨域。
if v := strings.TrimSpace(os.Getenv("CORS_ALLOW_ORIGINS")); v != "" {
parts := strings.Split(v, ",")
c.CORS.AllowOrigins = make([]string, 0, len(parts))
for _, p := range parts {
if p = strings.TrimSpace(p); p != "" {
c.CORS.AllowOrigins = append(c.CORS.AllowOrigins, p)
}
}
}
envBool("RATE_LIMIT_ENABLED", &c.RateLimit.Enabled)
envInt("RATE_LIMIT_RPS", &c.RateLimit.RPS)
envInt("RATE_LIMIT_BURST", &c.RateLimit.Burst)
envStr("UPLOAD_DIR", &c.Upload.Dir)
envStr("UPLOAD_URL_PREFIX", &c.Upload.URLPrefix)
@ -383,6 +411,12 @@ func (c *Config) normalize() {
if c.JWT.RefreshExpireHours <= 0 {
c.JWT.RefreshExpireHours = 720
}
if c.RateLimit.RPS <= 0 {
c.RateLimit.RPS = 20
}
if c.RateLimit.Burst <= 0 {
c.RateLimit.Burst = 40
}
if c.Upload.Dir == "" {
c.Upload.Dir = "./uploads"
}