diff --git a/src/main/java/com/uid2/shared/vertx/RequestCapturingHandler.java b/src/main/java/com/uid2/shared/vertx/RequestCapturingHandler.java index d837a8bb..46593fe1 100644 --- a/src/main/java/com/uid2/shared/vertx/RequestCapturingHandler.java +++ b/src/main/java/com/uid2/shared/vertx/RequestCapturingHandler.java @@ -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) { + 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(); } @@ -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); } } diff --git a/src/test/java/com/uid2/shared/vertx/RequestCapturingHandlerTest.java b/src/test/java/com/uid2/shared/vertx/RequestCapturingHandlerTest.java index b3f6b089..d96c602c 100644 --- a/src/test/java/com/uid2/shared/vertx/RequestCapturingHandlerTest.java +++ b/src/test/java/com/uid2/shared/vertx/RequestCapturingHandlerTest.java @@ -10,13 +10,16 @@ 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; @@ -24,15 +27,12 @@ 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) @@ -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) {