This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/master by this push:
new 60ebc53ed Feat: Reuse same RemoteRepository to HTTP URI creation logic
(#1878)
60ebc53ed is described below
commit 60ebc53ed202520beb165f9beb45eb755407a570
Author: Tamas Cservenak <[email protected]>
AuthorDate: Thu May 14 09:20:24 2026 +0200
Feat: Reuse same RemoteRepository to HTTP URI creation logic (#1878)
All HTTP remote repositories have pretty much same or similar expectations
regarding base URI of a HTTP remote repository.
---
.../aether/transport/apache/ApacheTransporter.java | 5 +-
.../aether/transport/jdk/JdkTransporter.java | 19 +---
.../aether/transport/jetty/JettyTransporter.java | 19 +---
.../transport/http/HttpTransporterUtils.java | 39 ++++++++
.../transport/http/HttpTransporterUtilsTest.java | 102 +++++++++++++++++++++
5 files changed, 144 insertions(+), 40 deletions(-)
diff --git
a/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporter.java
b/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporter.java
index 637ca130c..6d6e6e01a 100644
---
a/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporter.java
+++
b/maven-resolver-transport-apache/src/main/java/org/eclipse/aether/transport/apache/ApacheTransporter.java
@@ -160,10 +160,7 @@ final class ApacheTransporter extends AbstractTransporter
implements HttpTranspo
this.checksumExtractor = checksumExtractor;
this.pathProcessor = pathProcessor;
try {
- this.baseUri = new URI(repository.getUrl()).parseServerAuthority();
- if (baseUri.isOpaque()) {
- throw new URISyntaxException(repository.getUrl(), "URL must
not be opaque");
- }
+ this.baseUri = HttpTransporterUtils.getBaseUri(repository);
this.server = URIUtils.extractHost(baseUri);
if (server == null) {
throw new URISyntaxException(repository.getUrl(), "URL lacks
host name");
diff --git
a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java
b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java
index 7dc032898..ef7924335 100644
---
a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java
+++
b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java
@@ -177,24 +177,7 @@ final class JdkTransporter extends AbstractTransporter
implements HttpTransporte
this.checksumExtractor = checksumExtractor;
this.pathProcessor = pathProcessor;
try {
- URI uri = new URI(repository.getUrl()).parseServerAuthority();
- if (uri.isOpaque()) {
- throw new URISyntaxException(repository.getUrl(), "URL must
not be opaque");
- }
- if (uri.getRawFragment() != null || uri.getRawQuery() != null) {
- throw new URISyntaxException(repository.getUrl(), "URL must
not have fragment or query");
- }
- String path = uri.getPath();
- if (path == null) {
- path = "/";
- }
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
- if (!path.endsWith("/")) {
- path = path + "/";
- }
- this.baseUri = URI.create(uri.getScheme() + "://" +
uri.getRawAuthority() + path);
+ this.baseUri = HttpTransporterUtils.getBaseUri(repository);
} catch (URISyntaxException e) {
throw new NoTransporterException(repository, e.getMessage(), e);
}
diff --git
a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporter.java
b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporter.java
index 57fe17855..56b6417f8 100644
---
a/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporter.java
+++
b/maven-resolver-transport-jetty/src/main/java/org/eclipse/aether/transport/jetty/JettyTransporter.java
@@ -128,24 +128,7 @@ final class JettyTransporter extends AbstractTransporter
implements HttpTranspor
this.checksumExtractor = checksumExtractor;
this.pathProcessor = pathProcessor;
try {
- URI uri = new URI(repository.getUrl()).parseServerAuthority();
- if (uri.isOpaque()) {
- throw new URISyntaxException(repository.getUrl(), "URL must
not be opaque");
- }
- if (uri.getRawFragment() != null || uri.getRawQuery() != null) {
- throw new URISyntaxException(repository.getUrl(), "URL must
not have fragment or query");
- }
- String path = uri.getPath();
- if (path == null) {
- path = "/";
- }
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
- if (!path.endsWith("/")) {
- path = path + "/";
- }
- this.baseUri = URI.create(uri.getScheme() + "://" +
uri.getRawAuthority() + path);
+ this.baseUri = HttpTransporterUtils.getBaseUri(repository);
} catch (URISyntaxException e) {
throw new NoTransporterException(repository, e.getMessage(), e);
}
diff --git
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtils.java
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtils.java
index 0a6f2797a..19adce116 100644
---
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtils.java
+++
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtils.java
@@ -19,6 +19,8 @@
package org.eclipse.aether.util.connector.transport.http;
import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.Collections;
@@ -299,4 +301,41 @@ public final class HttpTransporterUtils {
}
return Optional.empty();
}
+
+ /**
+ * Shared code to create "base {@link URI}" for most common HTTP remote
repositories and all HTTP transports.
+ * Note: this method just applies common validation and adjustments to
URI, but it does not enforce protocol
+ * to be HTTP/HTTPS!
+ * <p>
+ * Validations and adjustments applied:
+ * <ul>
+ * <li>URI string is parsed from {@link RemoteRepository#getUrl()}
returned string</li>
+ * <li>URI must have parsable {@link URI#parseServerAuthority()}</li>
+ * <li>URI must not be opaque</li>
+ * <li>URI must not have fragment or query</li>
+ * <li>URI path is adjusted to end with {@code /} (slash).</li>
+ * </ul>
+ *
+ * @since 2.0.18
+ */
+ public static URI getBaseUri(RemoteRepository repository) throws
URISyntaxException {
+ URI uri = new URI(repository.getUrl()).parseServerAuthority();
+ if (uri.isOpaque()) {
+ throw new URISyntaxException(repository.getUrl(), "URL must not be
opaque");
+ }
+ if (uri.getRawFragment() != null || uri.getRawQuery() != null) {
+ throw new URISyntaxException(repository.getUrl(), "URL must not
have fragment or query");
+ }
+ String path = uri.getRawPath();
+ if (path == null) {
+ path = "/";
+ }
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+ if (!path.endsWith("/")) {
+ path = path + "/";
+ }
+ return new URI(uri.getScheme() + "://" + uri.getRawAuthority() + path);
+ }
}
diff --git
a/maven-resolver-util/src/test/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtilsTest.java
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtilsTest.java
new file mode 100644
index 000000000..4d3f8455e
--- /dev/null
+++
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/connector/transport/http/HttpTransporterUtilsTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.eclipse.aether.util.connector.transport.http;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.eclipse.aether.repository.RemoteRepository;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class HttpTransporterUtilsTest {
+ @Test
+ void goodUris() throws URISyntaxException {
+ URI uri;
+
+ // URI gets appended / (slash), if there is no trailing slash
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("as-is", "",
"https://host.com/base/").build());
+ assertEquals("https://host.com/base/", uri.toASCIIString());
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("slash-append", "",
"https://host.com/base").build());
+ assertEquals("https://host.com/base/", uri.toASCIIString());
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("root-append", "",
"https://host.com").build());
+ assertEquals("https://host.com/", uri.toASCIIString());
+ }
+
+ @Test
+ void badUris() {
+ assertThrows(
+ URISyntaxException.class,
+ () -> HttpTransporterUtils.getBaseUri(new
RemoteRepository.Builder("opaque", "", "is:opaque").build()));
+ assertThrows(
+ URISyntaxException.class,
+ () -> HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("query", "",
"https://host.com/path?query").build()));
+ assertThrows(
+ URISyntaxException.class,
+ () -> HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("fragment", "",
"https://host.com/path#fragment").build()));
+ }
+
+ @Test
+ void getBaseUriWithNonAscii() throws URISyntaxException {
+ URI uri;
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("repø", "default",
"https://host.dk/repø").build());
+ assertNotNull(uri);
+ assertEquals("https", uri.getScheme());
+ assertEquals("host.dk", uri.getHost());
+ assertEquals("/repø/", uri.getPath());
+ assertEquals("https://host.dk/rep%C3%B8/", uri.toASCIIString());
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("repø", "default",
"https://host.dk/rep%C3%B8").build());
+ assertNotNull(uri);
+ assertEquals("https", uri.getScheme());
+ assertEquals("host.dk", uri.getHost());
+ assertEquals("/repø/", uri.getPath());
+ assertEquals("https://host.dk/rep%C3%B8/", uri.toASCIIString());
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("räpo", "default",
"https://host.de/räpo").build());
+ assertNotNull(uri);
+ assertEquals("https", uri.getScheme());
+ assertEquals("host.de", uri.getHost());
+ assertEquals("/räpo/", uri.getPath());
+ assertEquals("https://host.de/r%C3%A4po/", uri.toASCIIString());
+
+ uri = HttpTransporterUtils.getBaseUri(
+ new RemoteRepository.Builder("räpo", "default",
"https://host.de/r%C3%A4po").build());
+ assertNotNull(uri);
+ assertEquals("https", uri.getScheme());
+ assertEquals("host.de", uri.getHost());
+ assertEquals("/räpo/", uri.getPath());
+ assertEquals("https://host.de/r%C3%A4po/", uri.toASCIIString());
+ }
+}