This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch feature/brotli-compression in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
commit 1423035b641e78aafb25591c46d3eced934a2696 Author: Konrad Windszus <[email protected]> AuthorDate: Mon Jan 19 09:22:11 2026 +0100 Support Brotli compression in JDK HTTP Client Enable Brotli/ZStandard in Jetty HTTP Client Add tests for compressed responses. This closes #1744 --- maven-resolver-test-http/pom.xml | 16 ++ .../aether/internal/test/util/http/HttpServer.java | 171 +++++++++++++++++++-- .../test/util/http/HttpTransporterTest.java | 67 ++++++-- .../src/main/resources/compressible-file.xml | 24 +++ .../transport/apache/ApacheTransporterTest.java | 6 + .../maven-resolver-transport-jdk/pom.xml | 4 + .../maven-resolver-transport-jdk11/pom.xml | 4 + .../aether/transport/jdk/JdkTransporterTest.java | 6 + maven-resolver-transport-jdk-parent/pom.xml | 5 + maven-resolver-transport-jetty/pom.xml | 14 +- .../transport/jetty/JettyTransporterTest.java | 7 + 11 files changed, 295 insertions(+), 29 deletions(-) diff --git a/maven-resolver-test-http/pom.xml b/maven-resolver-test-http/pom.xml index 9617490fa..647a15216 100644 --- a/maven-resolver-test-http/pom.xml +++ b/maven-resolver-test-http/pom.xml @@ -81,6 +81,18 @@ <groupId>org.eclipse.jetty.compression</groupId> <artifactId>jetty-compression-server</artifactId> </dependency> + <dependency> + <groupId>org.eclipse.jetty.compression</groupId> + <artifactId>jetty-compression-zstandard</artifactId> + </dependency> + <dependency> + <groupId>org.eclipse.jetty.compression</groupId> + <artifactId>jetty-compression-brotli</artifactId> + </dependency> + <dependency> + <groupId>org.eclipse.jetty.compression</groupId> + <artifactId>jetty-compression-gzip</artifactId> + </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> @@ -98,6 +110,10 @@ <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> diff --git a/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpServer.java b/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpServer.java index 0ca20510c..2bb63ee43 100644 --- a/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpServer.java +++ b/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpServer.java @@ -43,10 +43,16 @@ import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory; import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmHelper; import org.eclipse.aether.spi.connector.transport.http.RFC9457.RFC9457Payload; import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; +import org.eclipse.jetty.compression.server.CompressionConfig; +import org.eclipse.jetty.compression.server.CompressionHandler; import org.eclipse.jetty.http.DateGenerator; import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.pathmap.MatchedResource; +import org.eclipse.jetty.http.pathmap.PathMappings; +import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; import org.eclipse.jetty.io.Content; import org.eclipse.jetty.server.Handler; @@ -72,12 +78,16 @@ public class HttpServer { private final String path; - private final Map<String, String> headers; + private final Map<String, String> requestHeaders; - public LogEntry(String method, String path, Map<String, String> headers) { + private final Map<String, String> responseHeaders; + + public LogEntry( + String method, String path, Map<String, String> requestHeaders, Map<String, String> responseHeaders) { this.method = method; this.path = path; - this.headers = headers; + this.requestHeaders = requestHeaders; + this.responseHeaders = responseHeaders; } public String getMethod() { @@ -88,8 +98,12 @@ public class HttpServer { return path; } - public Map<String, String> getHeaders() { - return headers; + public Map<String, String> getRequestHeaders() { + return requestHeaders; + } + + public Map<String, String> getResponseHeaders() { + return responseHeaders; } @Override @@ -290,15 +304,15 @@ public class HttpServer { server = new Server(); httpConnector = new ServerConnector(server); server.addConnector(httpConnector); - server.setHandler(new Handler.Sequence( + + server.setHandler(new LogHandler(new CompressionEnforcingHandler(new Handler.Sequence( new ConnectionClosingHandler(), new ServerErrorHandler(), - new LogHandler(), new ProxyAuthHandler(), new AuthHandler(), new RedirectHandler(), new RepoHandler(), - new RFC9457Handler())); + new RFC9457Handler())))); server.start(); return this; @@ -313,6 +327,114 @@ public class HttpServer { } } + private class CompressionEnforcingHandler extends CompressionHandler { + // duplicate of CompressionHandler.pathConfigs which is private + private final PathMappings<CompressionConfig> pathConfigs = new PathMappings<>(); + + CompressionEnforcingHandler(Handler handler) { + super(handler); + this.putConfiguration( + "/br/*", + CompressionConfig.builder().compressIncludeEncoding("br").build()); + this.putConfiguration( + "/zstd/*", + CompressionConfig.builder().compressIncludeEncoding("zstd").build()); + this.putConfiguration( + "/gzip/*", + CompressionConfig.builder().compressIncludeEncoding("gzip").build()); + this.putConfiguration( + "/deflate/*", + CompressionConfig.builder() + .compressIncludeEncoding("deflate") + .build()); + } + + @Override + public CompressionConfig putConfiguration(PathSpec pathSpec, CompressionConfig config) { + // deliberately not set it in the super class yet + return pathConfigs.put(pathSpec, config); + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception { + Handler next = getHandler(); + if (next == null) { + return false; + } + String pathInContext = Request.getPathInContext(request); + MatchedResource<CompressionConfig> matchedConfig = this.pathConfigs.getMatched(pathInContext); + if (matchedConfig == null) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("skipping compression: path {} has no matching compression config", pathInContext); + } + // No configuration, skip + return next.handle(request, response, callback); + } + + // set the matched config in the super class for further processing, but for all paths + // no need to reset it later as this handler is not used among multiple requests + super.putConfiguration(PathSpec.from("/*"), matchedConfig.getResource()); + // first path segment determines the encoding, remove it from the request path for further processing + return super.handle(new StripLeadingPathSegmentsRequestWrapper(request, 1), response, callback); + } + } + + private static class StripLeadingPathSegmentsRequestWrapper extends Request.Wrapper { + private final int segmentsToStrip; + private final org.eclipse.jetty.http.HttpURI modifiedURI; + + StripLeadingPathSegmentsRequestWrapper(Request wrapped, int segmentsToStrip) { + super(wrapped); + this.segmentsToStrip = segmentsToStrip; + this.modifiedURI = stripPathSegments(wrapped.getHttpURI(), segmentsToStrip); + } + + private static org.eclipse.jetty.http.HttpURI stripPathSegments( + org.eclipse.jetty.http.HttpURI originalURI, int segmentsToStrip) { + if (segmentsToStrip <= 0) { + return originalURI; + } + + String originalPath = originalURI.getPath(); + if (originalPath == null || originalPath.isEmpty()) { + return originalURI; + } + + // Split path into segments + String[] segments = originalPath.split("/"); + StringBuilder newPath = new StringBuilder(); + + // Skip empty first segment (from leading /) and the specified number of segments + int skipCount = 0; + for (int i = 0; i < segments.length; i++) { + if (segments[i].isEmpty() && i == 0) { + // Skip leading empty segment from leading / + continue; + } + if (skipCount < segmentsToStrip) { + skipCount++; + continue; + } + newPath.append("/").append(segments[i]); + } + + // If we stripped everything, return root path + if (newPath.length() == 0) { + newPath.append("/"); + } + + // Build new URI with modified path + return org.eclipse.jetty.http.HttpURI.build(originalURI) + .path(newPath.toString()) + .asImmutable(); + } + + @Override + public org.eclipse.jetty.http.HttpURI getHttpURI() { + return modifiedURI; + } + } + private class ConnectionClosingHandler extends Handler.Abstract { @Override @@ -337,22 +459,39 @@ public class HttpServer { } } - private class LogHandler extends Handler.Abstract { + private class LogHandler extends Handler.Wrapper { + + public LogHandler(Handler handler) { + super(handler); + } + @Override - public boolean handle(Request req, Response response, Callback callback) { + public boolean handle(Request req, Response response, Callback callback) throws Exception { + LOGGER.info( "{} {}{}", req.getMethod(), req.getHttpURI().getDecodedPath(), req.getHttpURI().getQuery() != null ? "?" + req.getHttpURI().getQuery() : ""); - Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - for (HttpField header : req.getHeaders()) { - headers.put(header.getName(), header.getValueList().stream().collect(Collectors.joining(", "))); - } + Map<String, String> requestHeaders = + toUnmodifiableMap(req.getHeaders()); // capture request headers before other handlers modify them + boolean result = super.handle(req, response, callback); + // capture response headers after other handlers modified them logEntries.add(new LogEntry( - req.getMethod(), req.getHttpURI().getPathQuery(), Collections.unmodifiableMap(headers))); - return false; + req.getMethod(), + req.getHttpURI().getPathQuery(), + requestHeaders, + toUnmodifiableMap(response.getHeaders()))); + return result; + } + + Map<String, String> toUnmodifiableMap(HttpFields headers) { + Map<String, String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + for (HttpField header : headers) { + map.put(header.getName(), header.getValueList().stream().collect(Collectors.joining(", "))); + } + return Collections.unmodifiableMap(map); } } diff --git a/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java b/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java index 6f8e65294..a63de6dec 100644 --- a/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java +++ b/maven-resolver-test-http/src/main/java/org/eclipse/aether/internal/test/util/http/HttpTransporterTest.java @@ -35,6 +35,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import java.util.stream.Stream; import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositoryCache; @@ -66,6 +67,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static java.util.Objects.requireNonNull; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -74,12 +77,13 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Common set of tests against Http transporter. */ @SuppressWarnings({"checkstyle:MethodName"}) -public class HttpTransporterTest { +public abstract class HttpTransporterTest { protected static final Path KEY_STORE_PATH = Paths.get("target/keystore"); @@ -192,6 +196,10 @@ public class HttpTransporterTest { TestFileUtils.writeString(new File(repoDir, "dir/oldFile.txt"), "oldTest", OLD_FILE_TIMESTAMP); TestFileUtils.writeString(new File(repoDir, "empty.txt"), ""); TestFileUtils.writeString(new File(repoDir, "some space.txt"), "space"); + try (InputStream is = getCompressibleFileStream()) { + Files.copy(is, repoDir.toPath().resolve("compressible-file.xml")); + } + // TODO: populate larger file File resumable = new File(repoDir, "resume.txt"); TestFileUtils.writeString(resumable, "resumable"); resumable.setLastModified(System.currentTimeMillis() - 90 * 1000); @@ -199,6 +207,10 @@ public class HttpTransporterTest { newTransporter(httpServer.getHttpUrl()); } + private static InputStream getCompressibleFileStream() { + return HttpTransporterTest.class.getClassLoader().getResourceAsStream("compressible-file.xml"); + } + @AfterEach protected void tearDown() throws Exception { if (transporter != null) { @@ -431,15 +443,46 @@ public class HttpTransporterTest { assertEquals(OLD_FILE_TIMESTAMP, file.lastModified()); } - @Test - protected void testGet_CompressionUsedWithPom() throws Exception { - File file = TestFileUtils.createTempFile("pom"); - GetTask task = new GetTask(URI.create("repo/artifact.pom")).setDataPath(file.toPath()); + /** + * Provides compression algorithms supported by the transporter implementation. + * This should be the string value passed in the {@code Accept-Encoding} header. + * + * @return stream of supported compression algorithm names + * @see <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Encoding#directives">Accept-Encoding directives</a> + */ + protected abstract Stream<String> supportedCompressionAlgorithms(); + + @ParameterizedTest + // DEFLATE isn't supported by Jetty server (https://github.com/jetty/jetty.project/issues/280) + @ValueSource(strings = {"br", "gzip", "zstd"}) + void testGetWithCompression(String encoding) throws Exception { + assumeTrue( + supportedCompressionAlgorithms().anyMatch(supported -> supported.equals(encoding)), + () -> "Transporter does not support compression algorithm: " + encoding); + RecordingTransportListener listener = new RecordingTransportListener(); + // requires a file with at least 48/50 bytes (otherwise compression is disabled, + // https://github.com/jetty/jetty.project/blob/2264d3d9f9586f3e5e9040fba779ed72e931cb46/jetty-core/jetty-compression/jetty-compression-brotli/src/main/java/org/eclipse/jetty/compression/brotli/BrotliCompression.java#L61) + GetTask task = new GetTask(URI.create(encoding + "/repo/compressible-file.xml")).setListener(listener); transporter.get(task); - String acceptEncoding = httpServer.getLogEntries().get(0).getHeaders().get("Accept-Encoding"); + String acceptEncoding = + httpServer.getLogEntries().get(0).getRequestHeaders().get("Accept-Encoding"); assertNotNull(acceptEncoding, "Missing Accept-Encoding header when retrieving pom"); - // support either gzip or deflate as the transporter implementation may vary - assertTrue(acceptEncoding.contains("gzip") || acceptEncoding.contains("deflate")); + assertTrue(acceptEncoding.contains(encoding)); + // check original response header sent from server (client transparently handles compression and removes it) + for (HttpServer.LogEntry log : httpServer.getLogEntries()) { + assertEquals(encoding, log.getResponseHeaders().get("Content-Encoding")); + } + String expectedResourceData; + try (InputStream is = getCompressibleFileStream()) { + expectedResourceData = new String(is.readAllBytes(), StandardCharsets.UTF_8); + } + assertEquals(expectedResourceData, task.getDataString()); + assertEquals(0L, listener.getDataOffset()); + // data length is unknown as chunked transfer encoding is used with compression + assertEquals(-1, listener.getDataLength()); + assertEquals(1, listener.getStartedCount()); + assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount()); + assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8)); } @Test @@ -1235,7 +1278,7 @@ public class HttpTransporterTest { transporter.get(new GetTask(URI.create("repo/file.txt"))); assertEquals(1, httpServer.getLogEntries().size()); for (HttpServer.LogEntry log : httpServer.getLogEntries()) { - assertEquals("SomeTest/1.0", log.getHeaders().get("User-Agent")); + assertEquals("SomeTest/1.0", log.getRequestHeaders().get("User-Agent")); } } @@ -1251,7 +1294,7 @@ public class HttpTransporterTest { assertEquals(1, httpServer.getLogEntries().size()); for (HttpServer.LogEntry log : httpServer.getLogEntries()) { for (Map.Entry<String, String> entry : headers.entrySet()) { - assertEquals(entry.getValue(), log.getHeaders().get(entry.getKey()), entry.getKey()); + assertEquals(entry.getValue(), log.getRequestHeaders().get(entry.getKey()), entry.getKey()); } } } @@ -1321,8 +1364,8 @@ public class HttpTransporterTest { transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(1, httpServer.getLogEntries().size()); - assertNotNull(httpServer.getLogEntries().get(0).getHeaders().get("Authorization")); - assertNotNull(httpServer.getLogEntries().get(0).getHeaders().get("Proxy-Authorization")); + assertNotNull(httpServer.getLogEntries().get(0).getRequestHeaders().get("Authorization")); + assertNotNull(httpServer.getLogEntries().get(0).getRequestHeaders().get("Proxy-Authorization")); } @Test diff --git a/maven-resolver-test-http/src/main/resources/compressible-file.xml b/maven-resolver-test-http/src/main/resources/compressible-file.xml new file mode 100644 index 000000000..b32f390a0 --- /dev/null +++ b/maven-resolver-test-http/src/main/resources/compressible-file.xml @@ -0,0 +1,24 @@ +<metadata modelVersion="1.1.0"> +<groupId>org.apache.maven.plugins</groupId> +<artifactId>maven-jar-plugin</artifactId> +<version>3.0.3-SNAPSHOT</version> +<versioning> +<snapshot> +<timestamp>20171206.232134</timestamp> +<buildNumber>2496</buildNumber> +</snapshot> +<lastUpdated>20171206232134</lastUpdated> +<snapshotVersions> +<snapshotVersion> +<extension>jar</extension> +<value>3.0.3-20171206.232134-2496</value> +<updated>20171206232134</updated> +</snapshotVersion> +<snapshotVersion> +<extension>pom</extension> +<value>3.0.3-20171206.232134-2496</value> +<updated>20171206232134</updated> +</snapshotVersion> +</snapshotVersions> +</versioning> +</metadata> \ No newline at end of file diff --git a/maven-resolver-transport-apache/src/test/java/org/eclipse/aether/transport/apache/ApacheTransporterTest.java b/maven-resolver-transport-apache/src/test/java/org/eclipse/aether/transport/apache/ApacheTransporterTest.java index 027d605cd..56bf84540 100644 --- a/maven-resolver-transport-apache/src/test/java/org/eclipse/aether/transport/apache/ApacheTransporterTest.java +++ b/maven-resolver-transport-apache/src/test/java/org/eclipse/aether/transport/apache/ApacheTransporterTest.java @@ -21,6 +21,7 @@ package org.eclipse.aether.transport.apache; import java.io.File; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.util.stream.Stream; import org.apache.http.pool.ConnPoolControl; import org.apache.http.pool.PoolStats; @@ -47,6 +48,11 @@ class ApacheTransporterTest extends HttpTransporterTest { super(() -> new ApacheTransporterFactory(standardChecksumExtractor(), new PathProcessorSupport())); } + @Override + protected Stream<String> supportedCompressionAlgorithms() { + return Stream.of("gzip", "deflate"); + } + @Override @Disabled @Test diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml index ca0d4061a..e5cad9189 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml +++ b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml @@ -58,6 +58,10 @@ <groupId>com.github.mizosoft.methanol</groupId> <artifactId>methanol</artifactId> </dependency> + <dependency> + <groupId>com.github.mizosoft.methanol</groupId> + <artifactId>methanol-brotli</artifactId> + </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/pom.xml b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/pom.xml index 40ee490da..0e86cddfe 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/pom.xml +++ b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/pom.xml @@ -57,6 +57,10 @@ <groupId>com.github.mizosoft.methanol</groupId> <artifactId>methanol</artifactId> </dependency> + <dependency> + <groupId>com.github.mizosoft.methanol</groupId> + <artifactId>methanol-brotli</artifactId> + </dependency> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java index c480e8f55..cf37e4c2d 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java +++ b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk11/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java @@ -20,6 +20,7 @@ package org.eclipse.aether.transport.jdk; import java.net.ConnectException; import java.net.URI; +import java.util.stream.Stream; import org.eclipse.aether.internal.impl.DefaultPathProcessor; import org.eclipse.aether.internal.test.util.TestUtils; @@ -42,6 +43,11 @@ import static org.junit.jupiter.api.Assertions.fail; */ class JdkTransporterTest extends HttpTransporterTest { + @Override + protected Stream<String> supportedCompressionAlgorithms() { + return Stream.of("gzip", "deflate", "br"); + } + @Override @Disabled @Test diff --git a/maven-resolver-transport-jdk-parent/pom.xml b/maven-resolver-transport-jdk-parent/pom.xml index 2122794b5..36e5f24a3 100644 --- a/maven-resolver-transport-jdk-parent/pom.xml +++ b/maven-resolver-transport-jdk-parent/pom.xml @@ -45,6 +45,11 @@ <artifactId>methanol</artifactId> <version>1.9.0</version> </dependency> + <dependency> + <groupId>com.github.mizosoft.methanol</groupId> + <artifactId>methanol-brotli</artifactId> + <version>1.9.0</version> + </dependency> </dependencies> </dependencyManagement> </project> diff --git a/maven-resolver-transport-jetty/pom.xml b/maven-resolver-transport-jetty/pom.xml index c398e2901..2413c0c2b 100644 --- a/maven-resolver-transport-jetty/pom.xml +++ b/maven-resolver-transport-jetty/pom.xml @@ -72,7 +72,19 @@ <groupId>org.eclipse.jetty.http2</groupId> <artifactId>jetty-http2-client-transport</artifactId> </dependency> - + <!-- supported compressions --> + <dependency> + <groupId>org.eclipse.jetty.compression</groupId> + <artifactId>jetty-compression-gzip</artifactId> + </dependency> + <dependency> + <groupId>org.eclipse.jetty.compression</groupId> + <artifactId>jetty-compression-brotli</artifactId> + </dependency> + <dependency> + <groupId>org.eclipse.jetty.compression</groupId> + <artifactId>jetty-compression-zstandard</artifactId> + </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> diff --git a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/JettyTransporterTest.java b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/JettyTransporterTest.java index 94bfaa92e..4917ad734 100644 --- a/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/JettyTransporterTest.java +++ b/maven-resolver-transport-jetty/src/test/java/org/eclipse/aether/transport/jetty/JettyTransporterTest.java @@ -18,6 +18,8 @@ */ package org.eclipse.aether.transport.jetty; +import java.util.stream.Stream; + import org.eclipse.aether.internal.test.util.http.HttpTransporterTest; import org.eclipse.aether.spi.io.PathProcessorSupport; import org.junit.jupiter.api.Disabled; @@ -28,6 +30,11 @@ import org.junit.jupiter.api.Test; */ class JettyTransporterTest extends HttpTransporterTest { + @Override + protected Stream<String> supportedCompressionAlgorithms() { + return Stream.of("gzip", "deflate", "br", "zstd"); + } + @Override @Disabled @Test
