From d00086fd09f245c988570fc725570540de3e18aa Mon Sep 17 00:00:00 2001 From: Eunbin Son Date: Sat, 20 Jun 2026 08:02:57 +0900 Subject: [PATCH 1/2] Reject host-less endpoints in EndpointUtil.validateEndpoint --- .../exporter/internal/EndpointUtil.java | 4 ++ .../exporter/internal/EndpointUtilTest.java | 47 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java diff --git a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/EndpointUtil.java b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/EndpointUtil.java index c347d738edd..5f634ee9e15 100644 --- a/exporters/common/src/main/java/io/opentelemetry/exporter/internal/EndpointUtil.java +++ b/exporters/common/src/main/java/io/opentelemetry/exporter/internal/EndpointUtil.java @@ -30,6 +30,10 @@ public static URI validateEndpoint(String endpoint) { throw new IllegalArgumentException( "Invalid endpoint, must start with http:// or https://: " + uri); } + if (uri.getHost() == null) { + throw new IllegalArgumentException( + "Invalid endpoint, must start with http:// or https://: " + uri); + } return uri; } diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java new file mode 100644 index 00000000000..72e368acf4c --- /dev/null +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.exporter.internal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URI; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +class EndpointUtilTest { + + @ParameterizedTest + @MethodSource("validEndpoints") + void validateEndpoint_valid(String endpoint) { + assertThat(EndpointUtil.validateEndpoint(endpoint)).isEqualTo(URI.create(endpoint)); + } + + private static Stream validEndpoints() { + return Stream.of( + Arguments.argumentSet("http", "http://localhost:4318"), + Arguments.argumentSet("https", "https://localhost:4317"), + Arguments.argumentSet("path", "http://localhost:4318/v1/traces"), + Arguments.argumentSet("userinfo", "http://foo:bar@localhost:4317/path")); + } + + @ParameterizedTest + @ValueSource( + strings = { + "http:localhost:4317", // opaque, no host + "https:/foo", // single slash, no host + "localhost", // no scheme + "gopher://localhost" // wrong scheme + }) + void validateEndpoint_invalid(String endpoint) { + assertThatThrownBy(() -> EndpointUtil.validateEndpoint(endpoint)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("must start with http:// or https://"); + } +} From 1a2b01ae3015a10e1b1c54961b0f41a53e2ed37a Mon Sep 17 00:00:00 2001 From: Eunbin Son Date: Tue, 23 Jun 2026 07:58:46 +0900 Subject: [PATCH 2/2] Use Stream with argumentSet for invalid endpoint cases Convert validateEndpoint_invalid from @ValueSource to @MethodSource with named Arguments.argumentSet cases, matching the validEndpoints style in the same test class. No change to what the test asserts. Generated-by: Claude Code --- .../exporter/internal/EndpointUtilTest.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java index 72e368acf4c..1c81213c416 100644 --- a/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java +++ b/exporters/common/src/test/java/io/opentelemetry/exporter/internal/EndpointUtilTest.java @@ -13,7 +13,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; class EndpointUtilTest { @@ -32,16 +31,18 @@ private static Stream validEndpoints() { } @ParameterizedTest - @ValueSource( - strings = { - "http:localhost:4317", // opaque, no host - "https:/foo", // single slash, no host - "localhost", // no scheme - "gopher://localhost" // wrong scheme - }) + @MethodSource("invalidEndpoints") void validateEndpoint_invalid(String endpoint) { assertThatThrownBy(() -> EndpointUtil.validateEndpoint(endpoint)) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("must start with http:// or https://"); } + + private static Stream invalidEndpoints() { + return Stream.of( + Arguments.argumentSet("opaque, no host", "http:localhost:4317"), + Arguments.argumentSet("single slash, no host", "https:/foo"), + Arguments.argumentSet("no scheme", "localhost"), + Arguments.argumentSet("wrong scheme", "gopher://localhost")); + } }