@Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { // This won't work if you are HTTP proxies fronting the servlet String clientIp = request.getRemoteAddr(); if (rateLimiter.overLimitWhenIncremented("remote-ip:" + clientIp)) { response.setStatus(429); } else { response.setStatus(200); response.setContentType("text/html;charset=UTF-8"); try (PrintWriter out = response.getWriter()) { out.println("hello RateLimiterJ"); } } }
boolean overLimit = rateLimit.overLimitWhenIncremented(key.toString()); if (overLimit) { if (!rateLimited.reportOnly()) {
@Test @DisplayName("should configure rate limiter") public void shouldReportOnly() { when(requestRateLimiterFactory.getInstance(anySet())).thenReturn(requestRateLimiter); when(requestRateLimiter.overLimitWhenIncremented(anyString())).thenReturn(true); Response response = rule.getJerseyTest().target("/test/reportOnly/{id}").resolveTemplate("id", 1) .request(MediaType.APPLICATION_JSON_TYPE) .get(); assertThat(response.getStatus()).isEqualTo(200); }
@Test @DisplayName("should not limit request") public void shouldNotLimit() { when(requestRateLimiterFactory.getInstance(anySet())).thenReturn(requestRateLimiter); when(requestRateLimiter.overLimitWhenIncremented(anyString())).thenReturn(false); Response response = rule.getJerseyTest().target("/test/{id}").resolveTemplate("id", 1) .request(MediaType.APPLICATION_JSON_TYPE) .get(); assertThat(response.getStatus()).isEqualTo(200); }
@Test @DisplayName("should not limit if the backing rate limiter throws exception") public void shouldNotLimitIfBackingRateLimiterFails() { when(requestRateLimiterFactory.getInstance(anySet())).thenReturn(requestRateLimiter); when(requestRateLimiter.overLimitWhenIncremented(anyString())).thenThrow(new RuntimeException()); Response response = rule.getJerseyTest().target("/test/{id}").resolveTemplate("id", 1) .request(MediaType.APPLICATION_JSON_TYPE) .get(); assertThat(response.getStatus()).isEqualTo(200); }
@Test @DisplayName("should limit request returning a 429") public void shouldLimit() { when(requestRateLimiterFactory.getInstance(anySet())).thenReturn(requestRateLimiter); when(requestRateLimiter.overLimitWhenIncremented(anyString())).thenReturn(true); Response response = rule.getJerseyTest().target("/test/{id}").resolveTemplate("id", 1) .request(MediaType.APPLICATION_JSON_TYPE) .get(); assertThat(response.getStatus()).isEqualTo(429); }
@Test void shouldEventuallyCleanUpExpiredKeys() throws Exception { ImmutableSet<RequestLimitRule> rules = ImmutableSet.of(RequestLimitRule.of(Duration.ofSeconds(2), 5)); RequestRateLimiter requestRateLimiter = getRateLimiter(rules, timeBandit); String key = "ip:127.0.0.5"; IntStream.rangeClosed(1, 5).forEach(value -> { timeBandit.addUnixTimeMilliSeconds(100L); assertThat(requestRateLimiter.overLimitWhenIncremented(key)).isFalse(); }); IMap<Object, Object> map = hz.getMap(key); while (map.size() != 0) { Thread.sleep(10); } assertThat(map.size()).isZero(); }
@Test @Disabled void shouldEventuallyCleanUpExpiredKeys() throws Exception { ImmutableSet<RequestLimitRule> rules = ImmutableSet.of(RequestLimitRule.of(Duration.ofSeconds(1), 5)); RequestRateLimiter requestRateLimiter = getRateLimiter(rules, timeBandit); String key = "ip:127.0.0.5"; IntStream.rangeClosed(1, 5).forEach(value -> { timeBandit.addUnixTimeMilliSeconds(100L); assertThat(requestRateLimiter.overLimitWhenIncremented(key)).isFalse(); }); while (expiryingKeyMap.size() != 0) { Thread.sleep(50); } assertThat(expiryingKeyMap.size()).isZero(); }