Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
16 changes: 12 additions & 4 deletions src/main/java/com/uid2/shared/vertx/RequestCapturingHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,19 @@ public void handle(RoutingContext context) {
}

long timestamp = System.currentTimeMillis();
String remoteClient = getClientAddress(context.request().remoteAddress());
String remoteClient = null;
try {
SocketAddress remoteAddress = context.request().remoteAddress();
remoteClient = getClientAddress(remoteAddress);
} catch (NullPointerException ex) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching a NullPointerException (NPE) directly is generally not ideal in Java. Instead, it's better to prevent the NPE by checking for null conditions before access

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem isn't that the return value is null. The NPE is thrown from within the vertx library.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore above, It is actually verx throw the NPE while passing the x-forward header and we have no control over it.

LOGGER.warn("remoteAddress() throws NullPointerException");
}

HttpMethod method = context.request().method();
String uri = context.request().uri();
HttpVersion version = context.request().version();
context.addBodyEndHandler(v -> captureNoThrow(context, timestamp, remoteClient, version, method, uri));
String finalRemoteClient = remoteClient;
context.addBodyEndHandler(v -> captureNoThrow(context, timestamp, finalRemoteClient, version, method, uri));
context.next();
}

Expand All @@ -80,8 +88,8 @@ private String getClientAddress(SocketAddress inetSocketAddress) {
private void captureNoThrow(RoutingContext context, long timestamp, String remoteClient, HttpVersion version, HttpMethod method, String uri) {
try {
capture(context, timestamp, remoteClient, version, method, uri);
} catch (Throwable t) {
LOGGER.error("capture() throws", t);
} catch (RuntimeException e) {
LOGGER.error("capture() throws", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.RequestOptions;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.AllowForwardHeaders;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.client.WebClient;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
import org.assertj.core.condition.AnyOf;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mock;
import org.mockito.Mockito;

import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;

@ExtendWith(VertxExtension.class)
Expand Down Expand Up @@ -147,6 +147,32 @@ public void captureUnknownPath(Vertx vertx, VertxTestContext testContext) {
}));
}

@Test
public void handleIncorrectRemoteAddress(Vertx vertx, VertxTestContext testContext) {
Router router = Router.router(vertx);
router.allowForward(AllowForwardHeaders.X_FORWARD);
router.route().handler(new RequestCapturingHandler(siteStore));

vertx.createHttpServer().requestHandler(router).listen(Port, testContext.succeeding(id -> {
WebClient client = WebClient.create(vertx);
RequestOptions requestOptions = new RequestOptions();
requestOptions.setHost("localhost");
requestOptions.setPort(Integer.valueOf(Port));
requestOptions.addHeader(HttpHeaders.createOptimized("X-Forwarded-Host"), "[2001:db8::1"); // Incorrect IPV6
client.request(HttpMethod.GET, requestOptions).sendJsonObject(new JsonObject(), testContext.succeeding(response -> testContext.verify(() -> {
Assertions.assertDoesNotThrow(() ->
Metrics.globalRegistry
.get("uid2.http_requests")
.tag("status", "404")
.tag("method", "GET")
.tag("path", "unknown")
.counter()
);
testContext.completeNow();
})));
}));
}

@ParameterizedTest
@MethodSource("siteIdRoutingContextData")
public void getSiteIdFromRoutingContextData(String key, Object value, String siteId, String siteName, Vertx vertx, VertxTestContext testContext) {
Expand Down
Loading