diff --git a/pom.xml b/pom.xml index c759746e..ea50188a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.uid2 uid2-shared - 11.3.4-alpha-333-SNAPSHOT + 11.3.4-alpha-334-SNAPSHOT ${project.groupId}:${project.artifactId} Library for all the shared uid2 operations https://github.com/IABTechLab/uid2docs diff --git a/src/main/java/com/uid2/shared/Utils.java b/src/main/java/com/uid2/shared/Utils.java index 92c9180b..230709ee 100644 --- a/src/main/java/com/uid2/shared/Utils.java +++ b/src/main/java/com/uid2/shared/Utils.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.uid2.shared.util.Mapper; +import io.vertx.core.http.impl.HttpUtils; import io.vertx.core.json.Json; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; @@ -190,4 +191,20 @@ public static MessageDigest createMessageDigestSHA512() { throw new RuntimeException(e); } } + + public static String getNormalizedHttpPath(String path) { + String normalized = HttpUtils.normalizePath(path); + + int splitIndex = normalized.indexOf('?'); + if (splitIndex != -1) { + normalized = normalized.substring(0, splitIndex); + } + + if (normalized.charAt(normalized.length() - 1) == '/') { + normalized = normalized.substring(0, normalized.length() - 1); + } + normalized = normalized.toLowerCase(); + + return normalized; + } } diff --git a/src/main/java/com/uid2/shared/util/HTTPPathMetricFilter.java b/src/main/java/com/uid2/shared/util/HTTPPathMetricFilter.java index 6c8f645d..ba7ffaae 100644 --- a/src/main/java/com/uid2/shared/util/HTTPPathMetricFilter.java +++ b/src/main/java/com/uid2/shared/util/HTTPPathMetricFilter.java @@ -1,16 +1,12 @@ package com.uid2.shared.util; -import io.vertx.core.http.impl.HttpUtils; +import com.uid2.shared.Utils; import java.util.Set; public class HTTPPathMetricFilter { public static String filterPath(String actualPath, Set pathSet) { try { - String normalized = HttpUtils.normalizePath(actualPath).split("\\?")[0]; - if (normalized.charAt(normalized.length() - 1) == '/') { - normalized = normalized.substring(0, normalized.length() - 1); - } - normalized = normalized.toLowerCase(); + String normalized = Utils.getNormalizedHttpPath(actualPath); if (pathSet == null || pathSet.isEmpty()) { return normalized; } @@ -25,4 +21,18 @@ public static String filterPath(String actualPath, Set pathSet) { return "/parsing_error"; } } + + public static String filterPathWithoutPathParameters(String actualPath, Set pathSet) { + try { + String normalized = Utils.getNormalizedHttpPath(actualPath); + + if (pathSet == null || pathSet.isEmpty()) { return normalized; } + + if (pathSet.contains(normalized)) { return normalized; } + + return "/unknown"; + } catch (IllegalArgumentException e) { + return "/parsing_error"; + } + } } diff --git a/src/test/java/com/uid2/shared/util/HTTPPathMetricFilterTest.java b/src/test/java/com/uid2/shared/util/HTTPPathMetricFilterTest.java index fac26482..94d1ff6a 100644 --- a/src/test/java/com/uid2/shared/util/HTTPPathMetricFilterTest.java +++ b/src/test/java/com/uid2/shared/util/HTTPPathMetricFilterTest.java @@ -8,7 +8,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class HTTPPathMetricFilterTest { +public class HTTPPathMetricFilterTest { + /* filterPathTests */ final Set pathSet = Set.of("/v1/identity/map", "/token/refresh", "/list", "/list/:siteId/:keyId"); @ParameterizedTest @@ -54,4 +55,49 @@ void testPathFiltering_ValidPaths_KnownEndpoints(String actualPath, String expec String filteredPath = HTTPPathMetricFilter.filterPath(actualPath, pathSet); assertEquals(expectedFilteredPath, filteredPath); } + + /* filterPathWithoutPathParameters tests */ + final Set pathSetWithoutParams = Set.of("/v1/identity/map", "/token/refresh", "/list"); + + @ParameterizedTest + @ValueSource(strings = { + "", + "/", + "/unknown-path", + "../", + "/v1/identity/map%55", + "/list/123", + }) + void testPathFilteringWithoutPathParameters_InvalidPaths_Unknown(String actualPath) { + String filteredPath = HTTPPathMetricFilter.filterPathWithoutPathParameters(actualPath, pathSetWithoutParams); + assertEquals("/unknown", filteredPath); + } + + @ParameterizedTest + @ValueSource(strings = { + "v1/identity/map?id=bad-escape-code%2", + "token/refresh?refresh_token=SOME_TOKEN<%=7485*4353%>", + "list/12%4/5435" + }) + void testPathFilteringWithoutPathParameters_InvalidPaths_ParsingError(String actualPath) { + String filteredPath = HTTPPathMetricFilter.filterPathWithoutPathParameters(actualPath, pathSetWithoutParams); + assertEquals("/parsing_error", filteredPath); + } + + @ParameterizedTest + @CsvSource(value = { + "/v1/identity/map, /v1/identity/map", + "v1/identity/map, /v1/identity/map", + "V1/IdenTity/mAp, /v1/identity/map", + "./v1//identity//map/, /v1/identity/map", + "../v1/identity/./map, /v1/identity/map", + "/v1/identity/new/path/../../map, /v1/identity/map", + "token/refresh?refresh_token=123%20%23, /token/refresh", + "v1/identity/map?identity/../map/, /v1/identity/map", + "/list, /list" + }) + void testPathFilteringWithoutPathParameters_ValidPaths_KnownEndpoints(String actualPath, String expectedFilteredPath) { + String filteredPath = HTTPPathMetricFilter.filterPathWithoutPathParameters(actualPath, pathSetWithoutParams); + assertEquals(expectedFilteredPath, filteredPath); + } }