diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/AddressNormalizer.java b/sdk/src/main/java/io/opentdf/platform/sdk/AddressNormalizer.java index 48a86ac7..93692323 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/AddressNormalizer.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/AddressNormalizer.java @@ -6,6 +6,8 @@ import java.net.URI; import java.net.URISyntaxException; +import static java.lang.String.format; + class AddressNormalizer { private static final Logger logger = LoggerFactory.getLogger(AddressNormalizer.class); @@ -13,12 +15,7 @@ private AddressNormalizer(){ } static String normalizeAddress(String urlString, boolean usePlaintext) { - URI uri; - try { - uri = new URI(urlString); - } catch (URISyntaxException e) { - throw new SDKException("error trying to parse URL [" + urlString + "]", e); - } + URI uri = getInitialUri(urlString); final String scheme = usePlaintext ? "http" : "https"; if (uri.getHost() == null) { @@ -53,4 +50,25 @@ static String normalizeAddress(String urlString, boolean usePlaintext) { throw new SDKException("error creating KAS address", e); } } + + // tries to parse a URI that is possibly missing a scheme by first trying the input directly, and then + // trying again with a fake scheme if the first attempt fails. this is needed because URIs without a schema + // whose hostnames are not valid schemas will fail to parse + private static URI getInitialUri(String urlString) { + URISyntaxException initialThrown = null; + try { + return new URI(urlString); + } catch (URISyntaxException e) { + // this can happen if there is no schema and the hostname is not a valid scheme, like if we havea + // an IP adddress + initialThrown = e; + } + + try { + return new URI(format("fake://%s", urlString)); + } catch (URISyntaxException e) { + initialThrown.addSuppressed(e); + throw new SDKException("error parsing url [" + urlString + "]", initialThrown); + } + } } diff --git a/sdk/src/test/java/io/opentdf/platform/sdk/AddressNormalizerTest.java b/sdk/src/test/java/io/opentdf/platform/sdk/AddressNormalizerTest.java index 154bf1e7..20f9817e 100644 --- a/sdk/src/test/java/io/opentdf/platform/sdk/AddressNormalizerTest.java +++ b/sdk/src/test/java/io/opentdf/platform/sdk/AddressNormalizerTest.java @@ -3,6 +3,8 @@ import org.junit.jupiter.api.Test; +import java.net.URISyntaxException; + import static io.opentdf.platform.sdk.AddressNormalizer.normalizeAddress; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -16,6 +18,8 @@ void testAddressNormalizationWithHTTPSClient() { assertThat(normalizeAddress("example.org:1234", false)).isEqualTo("https://example.org:1234"); assertThat(normalizeAddress("ftp://example.org", false)).isEqualTo("https://example.org:443"); assertThat(normalizeAddress("keycloak.vm", false)).isEqualTo("https://keycloak.vm:443"); + assertThat(normalizeAddress("192.168.1.1:1234", false)).isEqualTo("https://192.168.1.1:1234"); + assertThat(normalizeAddress("192.168.1.1", false)).isEqualTo("https://192.168.1.1:443"); } @Test @@ -26,6 +30,8 @@ void testAddressNormaliationWithInsecureHTTPClient() { assertThat(normalizeAddress("example.org:1234", true)).isEqualTo("http://example.org:1234"); assertThat(normalizeAddress("sftp://example.org", true)).isEqualTo("http://example.org:80"); assertThat(normalizeAddress("keycloak.vm", true)).isEqualTo("http://keycloak.vm:80"); + assertThat(normalizeAddress("192.168.1.1:1234", true)).isEqualTo("http://192.168.1.1:1234"); + assertThat(normalizeAddress("192.168.1.1", true)).isEqualTo("http://192.168.1.1:80"); } @Test @@ -36,4 +42,10 @@ void testAddressNormalizationWithInvalidPort() { thrown = assertThrows(SDKException.class, () -> normalizeAddress("http://example.org:notaport", true)); assertThat(thrown.getMessage()).contains("http://example.org:notaport"); } + + @Test + void testInsaneAddressThrowsException() { + var thrown = assertThrows(SDKException.class, () -> normalizeAddress("1://&()&{$!//1//1", true)); + assertThat(thrown.getCause()).isInstanceOf(URISyntaxException.class); + } }