Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x] - Add Max Re-Route configurable #5587

Merged
merged 4 commits into from
Dec 2, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add Max Re-Route configurable.
  • Loading branch information
dalexandrov committed Dec 2, 2022
commit 6ec661a692ead6f50eedf9ab140d0f34fc66e4a8
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ public final class HttpRouting implements Routing {
private final ServiceRoute rootRoute;
private final ErrorHandlers errorHandlers;
private final List<HttpFeature> features;
private final int maxReRouteCount;

private HttpRouting(Builder builder) {
this.errorHandlers = ErrorHandlers.create(builder.errorHandlers);
this.filters = Filters.create(errorHandlers, List.copyOf(builder.filters));
this.rootRoute = builder.rootRules.build();
this.features = List.copyOf(builder.features);

this.maxReRouteCount = builder.maxReRouteCount;
}

/**
Expand Down Expand Up @@ -96,7 +97,7 @@ public static HttpRouting empty() {
* @param response routing response
*/
public void route(ConnectionContext ctx, RoutingRequest request, RoutingResponse response) {
RoutingExecutor routingExecutor = new RoutingExecutor(ctx, rootRoute, request, response);
RoutingExecutor routingExecutor = new RoutingExecutor(ctx, rootRoute, request, response, maxReRouteCount);
// we cannot throw an exception to the filters, as then the filter would not have information about actual status
// code, so error handling is done in routing executor and for each filter
filters.filter(ctx, request, response, routingExecutor);
Expand Down Expand Up @@ -130,6 +131,7 @@ public static class Builder implements HttpRules, io.helidon.common.Builder<Buil
private final ServiceRules rootRules = new ServiceRules();
private final List<HttpFeature> features = new ArrayList<>();
private final Map<Class<? extends Throwable>, ErrorHandler<?>> errorHandlers = new IdentityHashMap<>();
private int maxReRouteCount;

private Builder() {
}
Expand Down Expand Up @@ -319,22 +321,37 @@ public Builder any(String pattern, Handler handler) {
.path(pattern)
.handler(handler));
}

/**
* Set max reroute count.
*
* @param maxReRouteCount
* @return updated builder
*/
public Builder maxReRouteCount(int maxReRouteCount){
this.maxReRouteCount = maxReRouteCount;
return this;
}

}

private static final class RoutingExecutor implements Callable<Void> {
private final ConnectionContext ctx;
private final RoutingRequest request;
private final RoutingResponse response;
private final ServiceRoute rootRoute;
private final int maxReRouteCount;

private RoutingExecutor(ConnectionContext ctx,
ServiceRoute rootRoute,
RoutingRequest request,
RoutingResponse response) {
RoutingResponse response,
int maxReRouteCount) {
this.ctx = ctx;
this.rootRoute = rootRoute;
this.request = request;
this.response = response;
this.maxReRouteCount = maxReRouteCount;
}

@Override
Expand All @@ -353,8 +370,9 @@ public Void call() throws Exception {
int counter = 0;
while (result == RoutingResult.ROUTE) {
counter++;
if (counter == 9) {
LOGGER.log(System.Logger.Level.ERROR, "Rerouted more than 10 times. Will not attempt further routing");
if (counter == maxReRouteCount) {
LOGGER.log(System.Logger.Level.ERROR, "Rerouted more than " + maxReRouteCount
+ " times. Will not attempt further routing");

throw new HttpException("Too many reroutes", Http.Status.INTERNAL_SERVER_ERROR_500, true);
}
Expand Down