6 files changed,
51 insertions(+),
18 deletions(-)
Author:
Olexandr Smirnov
ss2316544@gmail.com
Committed by:
GitHub
noreply@github.com
Committed at:
2025-07-15 14:03:33 +0300
Parent:
d309c75
M
cmd/api/main.go
··· 124 124 Burst: cfg.RateLimiterBurst, 125 125 } 126 126 127 + slowRateLimiterConfig := ratelimit.Config{ 128 + RPS: cfg.SlowRateLimiterRPS, 129 + TTL: cfg.SlowRateLimiterTTL, 130 + Burst: cfg.SlowRateLimiterBurst, 131 + } 132 + 127 133 handler := httptransport.NewTransport( 128 134 usersrv, 129 135 notesrv, ··· 132 138 cfg.CORSAllowedOrigins, 133 139 cfg.CORSMaxAge, 134 140 rateLimiterConfig, 141 + slowRateLimiterConfig, 135 142 ) 136 143 137 144 // http server
M
internal/config/config.go
··· 60 60 LogFormat string 61 61 LogShowLine bool 62 62 63 - RateLimiterRPS int 64 - RateLimiterBurst int 65 - RateLimiterTTL time.Duration 63 + RateLimiterRPS int 64 + RateLimiterBurst int 65 + RateLimiterTTL time.Duration 66 + SlowRateLimiterRPS int 67 + SlowRateLimiterBurst int 68 + SlowRateLimiterTTL time.Duration 66 69 } 67 70 68 71 func NewConfig() *Config { ··· 116 119 LogFormat: getenvOrDefault("LOG_FORMAT", "json"), 117 120 LogShowLine: getenvOrDefault("LOG_SHOW_LINE", "true") == "true", 118 121 119 - RateLimiterRPS: mustGetenvOrDefaultInt("RATELIMITER_RPS", 100), 120 - RateLimiterBurst: mustGetenvOrDefaultInt("RATELIMITER_BURST", 10), 121 - RateLimiterTTL: mustParseDuration(getenvOrDefault("RATELIMITER_TTL", "1m")), 122 + RateLimiterRPS: mustGetenvOrDefaultInt("RATELIMITER_RPS", 100), 123 + RateLimiterBurst: mustGetenvOrDefaultInt("RATELIMITER_BURST", 10), 124 + RateLimiterTTL: mustParseDuration(getenvOrDefault("RATELIMITER_TTL", "1m")), 125 + SlowRateLimiterRPS: mustGetenvOrDefaultInt("SLOW_RATELIMITER_RPS", 2), 126 + SlowRateLimiterBurst: mustGetenvOrDefaultInt("SLOW_RATELIMITER_BURST", 2), 127 + SlowRateLimiterTTL: mustParseDuration(getenvOrDefault("SLOW_RATELIMITER_TTL", "1m")), 122 128 } 123 129 } 124 130
M
internal/transport/http/apiv1/apiv1.go
··· 5 5 "github.com/olexsmir/onasty/internal/config" 6 6 "github.com/olexsmir/onasty/internal/service/notesrv" 7 7 "github.com/olexsmir/onasty/internal/service/usersrv" 8 + "github.com/olexsmir/onasty/internal/transport/http/ratelimit" 8 9 ) 9 10 10 11 type APIV1 struct { 11 - usersrv usersrv.UserServicer 12 - notesrv notesrv.NoteServicer 13 - env config.Environment 14 - domain string 12 + usersrv usersrv.UserServicer 13 + notesrv notesrv.NoteServicer 14 + slowRatelimitCfg ratelimit.Config 15 + env config.Environment 16 + domain string 15 17 } 16 18 17 19 func NewAPIV1( 18 20 us usersrv.UserServicer, 19 21 ns notesrv.NoteServicer, 22 + slowRatelimitCfg ratelimit.Config, 20 23 env config.Environment, 21 24 domain string, 22 25 ) *APIV1 { 23 26 return &APIV1{ 24 - usersrv: us, 25 - notesrv: ns, 26 - env: env, 27 - domain: domain, 27 + usersrv: us, 28 + notesrv: ns, 29 + slowRatelimitCfg: slowRatelimitCfg, 30 + env: env, 31 + domain: domain, 28 32 } 29 33 } 30 34 ··· 36 40 auth.POST("/signin", a.signInHandler) 37 41 auth.POST("/refresh-tokens", a.refreshTokensHandler) 38 42 auth.GET("/verify/:token", a.verifyHandler) 39 - auth.POST("/resend-verification-email", a.resendVerificationEmailHandler) 40 - auth.POST("/reset-password", a.requestResetPasswordHandler) 43 + auth.POST("/resend-verification-email", a.slowRateLimit(), a.resendVerificationEmailHandler) 44 + auth.POST("/reset-password", a.slowRateLimit(), a.requestResetPasswordHandler) 41 45 auth.POST("/reset-password/:token", a.resetPasswordHandler) 42 46 43 47 oauth := r.Group("/oauth") ··· 75 79 } 76 80 } 77 81 } 82 + 83 +func (a *APIV1) slowRateLimit() gin.HandlerFunc { 84 + return ratelimit.MiddlewareWithConfig(a.slowRatelimitCfg) 85 +}
M
internal/transport/http/http.go
··· 23 23 corsAllowedOrigins []string 24 24 corsMaxAge time.Duration 25 25 ratelimitCfg ratelimit.Config 26 + slowRatelimitCfg ratelimit.Config 26 27 } 27 28 28 29 func NewTransport( ··· 33 34 corsAllowedOrigins []string, 34 35 corsMaxAge time.Duration, 35 36 ratelimitCfg ratelimit.Config, 37 + slowRatelimitCfg ratelimit.Config, 36 38 ) *Transport { 37 39 return &Transport{ 38 40 usersrv: us, ··· 42 44 corsAllowedOrigins: corsAllowedOrigins, 43 45 corsMaxAge: corsMaxAge, 44 46 ratelimitCfg: ratelimitCfg, 47 + slowRatelimitCfg: slowRatelimitCfg, 45 48 } 46 49 } 47 50 ··· 56 59 ) 57 60 58 61 api := r.Group("/api") 59 - api.GET("/ping", t.pingHandler) 60 - apiv1.NewAPIV1(t.usersrv, t.notesrv, t.env, t.domain).Routes(api.Group("/v1")) 62 + { 63 + api.GET("/ping", t.pingHandler) 64 + apiv1. 65 + NewAPIV1(t.usersrv, t.notesrv, t.slowRatelimitCfg, t.env, t.domain). 66 + Routes(api.Group("/v1")) 67 + } 61 68 62 69 return r.Handler() 63 70 }