22
33import io .github .bucket4j .Bandwidth ;
44import io .github .bucket4j .Bucket ;
5- import io .github .bucket4j .BucketConfiguration ;
6- import io .github .bucket4j .distributed .proxy .ProxyManager ;
7- import io .github .bucket4j .redis .lettuce .cas .LettuceBasedProxyManager ;
8-
9- import io .lettuce .core .RedisClient ;
10- import io .lettuce .core .RedisURI ;
115
126import jakarta .servlet .FilterChain ;
137import jakarta .servlet .ServletException ;
148import jakarta .servlet .http .HttpServletRequest ;
159import jakarta .servlet .http .HttpServletResponse ;
1610
17- import org .springframework .beans .factory .annotation .Value ;
1811import org .springframework .context .annotation .Profile ;
1912import org .springframework .stereotype .Component ;
2013import org .springframework .web .filter .OncePerRequestFilter ;
2114
2215import java .io .IOException ;
2316import java .time .Duration ;
17+ import java .util .Map ;
2418import java .util .Optional ;
19+ import java .util .concurrent .ConcurrentHashMap ;
2520
26- @ Component
27- @ Profile ("prod" )
28- public class RedisRateLimitFilter extends OncePerRequestFilter {
29-
30- private final ProxyManager <byte []> proxyManager ;
31-
32- public RedisRateLimitFilter (
33- @ Value ("${spring.data.redis.host}" ) String host ,
34- @ Value ("${spring.data.redis.port}" ) int port
35- ) {
36-
37- RedisURI redisURI = RedisURI .Builder .redis (host )
38- .withPort (port )
39- .build ();
40-
41- RedisClient redisClient = RedisClient .create (redisURI );
21+ public class IpRateLimitFilter extends OncePerRequestFilter {
4222
43- this .proxyManager = LettuceBasedProxyManager
44- .builderFor (redisClient )
45- .build ();
46- }
23+ private final Map <String , Bucket > buckets = new ConcurrentHashMap <>();
4724
48- private BucketConfiguration configuration () {
49- return BucketConfiguration .builder ()
25+ private Bucket createBucket () {
26+ return Bucket .builder ()
5027 .addLimit (Bandwidth .simple (10 , Duration .ofMinutes (1 )))
5128 .build ();
5229 }
@@ -57,7 +34,7 @@ protected void doFilterInternal(HttpServletRequest request,
5734 FilterChain filterChain )
5835 throws ServletException , IOException {
5936
60- if (!request .getRequestURI ().equals ("/api/v1/contact" )) {
37+ if (!request .getServletPath ().startsWith ("/api/v1/contact" )) {
6138 filterChain .doFilter (request , response );
6239 return ;
6340 }
@@ -66,8 +43,7 @@ protected void doFilterInternal(HttpServletRequest request,
6643 .map (s -> s .split ("," )[0 ].trim ())
6744 .orElse (request .getRemoteAddr ());
6845
69- Bucket bucket = proxyManager .builder ()
70- .build (("ip:" + ip ).getBytes (), this ::configuration );
46+ Bucket bucket = buckets .computeIfAbsent (ip , k -> createBucket ());
7147
7248 if (bucket .tryConsume (1 )) {
7349 filterChain .doFilter (request , response );
0 commit comments