Add rate limiting, CORS support, custom HTTP method annotations, and HTTP server enhancements
- Introduced rate limiting functionality with multiple algorithms (Token Bucket, Fixed Window, Leaky Bucket, Sliding Window) via `RateLimiter` interface. - Added CORS handling with `CorsConfig` and `CorsHandler` for flexible origin, headers, and method configuration. - Implemented support for custom HTTP methods via `PATCH` and `CUSTOM` annotations in `AnnotationScanner`. - Enhanced `HttpServer` to support builder pattern and optional integrations for CORS and rate limiting. - Updated `HttpRequestHandler` to incorporate CORS and rate limiting logic.
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package dev.coph.nextusweb.server;
|
||||
|
||||
import dev.coph.nextusweb.server.cores.CorsHandler;
|
||||
import dev.coph.nextusweb.server.ratelimit.RateLimitGate;
|
||||
import dev.coph.nextusweb.server.ratelimit.RateLimiter;
|
||||
import dev.coph.nextusweb.server.router.Request;
|
||||
import dev.coph.nextusweb.server.router.Response;
|
||||
import dev.coph.nextusweb.server.router.Router;
|
||||
@@ -10,6 +13,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.*;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -20,9 +24,14 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<FullHt
|
||||
Executors.newVirtualThreadPerTaskExecutor();
|
||||
|
||||
private final Router router;
|
||||
private final CorsHandler cors;
|
||||
private final RateLimitGate rateLimit;
|
||||
|
||||
public HttpRequestHandler(Router router) {
|
||||
|
||||
public HttpRequestHandler(Router router, CorsHandler cors, RateLimitGate rateLimit) {
|
||||
this.router = router;
|
||||
this.cors = cors;
|
||||
this.rateLimit = rateLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,7 +47,29 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<FullHt
|
||||
}
|
||||
|
||||
private void handle(ChannelHandlerContext ctx, FullHttpRequest raw) {
|
||||
String origin = raw.headers().get("Origin");
|
||||
|
||||
if (cors != null && cors.isPreflight(raw.method(), raw.headers())) {
|
||||
send(ctx, cors.handlePreflight(origin, raw.headers()));
|
||||
return;
|
||||
}
|
||||
|
||||
String path = new QueryStringDecoder(raw.uri()).path();
|
||||
|
||||
RateLimiter.Result rlResult = null;
|
||||
if (rateLimit != null) {
|
||||
String remote = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress();
|
||||
rlResult = rateLimit.check(raw, path, remote);
|
||||
if (rlResult != null && !rlResult.allowed()) {
|
||||
Response res = new Response().status(429).json("{\"error\":\"Too Many Requests\"}");
|
||||
RateLimitGate.applyHeaders(rlResult, res);
|
||||
if (cors != null) cors.applyHeaders(origin, res);
|
||||
send(ctx, res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Router.Resolution resolution = router.resolve(raw.method(), path);
|
||||
|
||||
Response res = new Response();
|
||||
@@ -67,6 +98,8 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<FullHt
|
||||
case Router.Resolution.NotFound nf -> res.status(404).json("{\"error\":\"Not Found\"}");
|
||||
}
|
||||
|
||||
RateLimitGate.applyHeaders(rlResult, res);
|
||||
if (cors != null) cors.applyHeaders(origin, res);
|
||||
send(ctx, res);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user