content: package com.github.aesteve.vertx.nubes.handlers.impl;
  
  import com.github.aesteve.vertx.nubes.Config;
  import com.github.aesteve.vertx.nubes.context.ClientAccesses;
  import com.github.aesteve.vertx.nubes.context.RateLimit;
  import io.vertx.core.Handler;
  import io.vertx.core.Vertx;
  import io.vertx.core.json.JsonObject;
  import io.vertx.core.shareddata.LocalMap;
  import io.vertx.ext.web.RoutingContext;
  
  public class RateLimitationHandler implements Handler<RoutingContext> {
  
    private final RateLimit rateLimit;
  
    private RateLimitationHandler(RateLimit rateLimit) {
      this.rateLimit = rateLimit;
    }
  
    public static RateLimitationHandler create(Config config) {
      return new RateLimitationHandler(config.getRateLimit());
    }
  
    @Override
    public void handle(RoutingContext context) {
      Vertx vertx = context.vertx();
      LocalMap<Object, Object> rateLimitations = vertx.sharedData().getLocalMap("mvc.rateLimitation");
      String clientIp = context.request().remoteAddress().host();
      JsonObject json = (JsonObject) rateLimitations.get(clientIp);
      ClientAccesses accesses;
      if (json == null) {
        accesses = new ClientAccesses();
      } else {
        accesses = ClientAccesses.fromJsonObject(json);
      }
      accesses.newAccess();
      rateLimitations.put(clientIp, accesses.toJsonObject());
      if (accesses.isOverLimit(rateLimit)) {
        context.fail(420);
      } else {
        context.next();
      }
    }
  
  }
  