我有一个 Vertx API,用户可以在其中执行 http POST,但我想限制来自垃圾邮件 API 调用的同一个人/IP 地址,例如在他们可以再次执行之前限制 30 秒的速率。
我可以在哪里以及如何在我的 vertx API 代码中实现这个速率限制?
这是我的开胃菜:
public class Starter extends AbstractVerticle {
private static final Logger LOGGER = Logger.getLogger(Starter.class.getSimpleName());
private static final String HTTP_PORT = "http.port";
private static final Integer HTTP_FALLBACK_PORT = 8000;
public Starter() {
}
@Override
public void start(Promise<Void> startPromise) throws ParseException {
vertx
.createHttpServer()
.requestHandler(buildRoutes(enableCors()))
.listen(config().getInteger(HTTP_PORT, HTTP_FALLBACK_PORT),
asyncResult -> listener(asyncResult, startPromise));
}
private Router buildRoutes(final Router router) throws ParseException {
new MovieApi(router);
router.errorHandler(500, this::handle500Error);
return router;
}
private void handle500Error(RoutingContext routingContext) {
LOGGER.log(Level.SEVERE, "Internal Server Error", routingContext.failure());
}
private Router enableCors() {
var router = Router.router(vertx);
router.route().handler(CorsHandler.create(".*.")
.allowedHeader("x-requested-with")
.allowedHeader("Access-Control-Allow-Origin")
.allowedHeader("origin")
.allowedHeader("Content-Type")
.allowedHeader("accept")
.allowedMethod(HttpMethod.GET)
.allowedMethod(HttpMethod.POST)
.allowedMethod(HttpMethod.DELETE)
.allowedMethod(HttpMethod.PUT));
router.route().handler(BodyHandler.create());
return router;
}
@Override
public void stop(Promise<Void> endFuture) {
vertx.close(completionHandler -> endFuture.complete());
}
private void listener(final AsyncResult<HttpServer> res, Promise<Void> startPromise) {
if (res.succeeded()) {
startPromise.complete();
LOGGER.log(Level.INFO,
() -> String.format("Server is listening on port: %s", res.result().actualPort()));
} else {
startPromise.fail("Failed to start http server");
LOGGER.log(Level.INFO,
() -> String.format("Failed to bind on port: %s", config()
.getInteger(HTTP_PORT, HTTP_FALLBACK_PORT)));
}
}
public static void main(String... args) {
var vertx = Vertx.vertx();
vertx.deployVerticle(Starter.class.getName());
}
}