This is an automated email from the ASF dual-hosted git repository. sjaranowski pushed a commit to branch maven-resolver-1.9.x in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/maven-resolver-1.9.x by this push: new fcc2fcc8 [MRESOLVER-703] Expose redirect config for http transport fcc2fcc8 is described below commit fcc2fcc8d5b55a594f03ae78206fbb38ad273657 Author: Slawomir Jaranowski <s.jaranow...@gmail.com> AuthorDate: Thu May 1 10:28:32 2025 +0200 [MRESOLVER-703] Expose redirect config for http transport --- .../eclipse/aether/ConfigurationProperties.java | 28 ++++++++++++++++++++++ .../aether/transport/http/HttpTransporter.java | 21 ++++++++++++---- src/site/markdown/configuration.md | 2 ++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java b/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java index 94a5fa27..86a5dc8b 100644 --- a/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java +++ b/maven-resolver-api/src/main/java/org/eclipse/aether/ConfigurationProperties.java @@ -306,6 +306,34 @@ public final class ConfigurationProperties { */ public static final boolean DEFAULT_PERSISTED_CHECKSUMS = true; + /** + * If enabled, the HTTP transport will follow HTTP redirects. + * + * @since 1.9.23 + */ + public static final String HTTP_FOLLOW_REDIRECTS = PREFIX_CONNECTOR + "http.followRedirects"; + + /** + * The default HTTP redirect mode if {@link #HTTP_FOLLOW_REDIRECTS} isn't set. + * + * @since 1.9.23 + */ + public static final boolean DEFAULT_FOLLOW_REDIRECTS = true; + + /** + * The max redirect count to follow for the HTTP transport. + * + * @since 1.9.23 + */ + public static final String HTTP_MAX_REDIRECTS = PREFIX_CONNECTOR + "http.maxRedirects"; + + /** + * The default max redirect count to follow for the HTTP transport. + * + * @since 1.9.23 + */ + public static final int DEFAULT_HTTP_MAX_REDIRECTS = 5; + private ConfigurationProperties() { // hide constructor } diff --git a/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java b/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java index d681e199..bfd6abc0 100644 --- a/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java +++ b/maven-resolver-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java @@ -79,6 +79,7 @@ import org.apache.http.impl.auth.SPNegoSchemeFactory; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.LaxRedirectStrategy; import org.apache.http.impl.client.StandardHttpRequestRetryHandler; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; @@ -263,6 +264,16 @@ final class HttpTransporter extends AbstractTransporter { HTTP_RETRY_HANDLER_REQUEST_SENT_ENABLED); String userAgent = ConfigUtils.getString( session, ConfigurationProperties.DEFAULT_USER_AGENT, ConfigurationProperties.USER_AGENT); + int maxRedirects = ConfigUtils.getInteger( + session, + ConfigurationProperties.DEFAULT_HTTP_MAX_REDIRECTS, + ConfigurationProperties.HTTP_MAX_REDIRECTS + "." + repository.getId(), + ConfigurationProperties.HTTP_MAX_REDIRECTS); + boolean followRedirects = ConfigUtils.getBoolean( + session, + ConfigurationProperties.DEFAULT_FOLLOW_REDIRECTS, + ConfigurationProperties.HTTP_FOLLOW_REDIRECTS + "." + repository.getId(), + ConfigurationProperties.HTTP_FOLLOW_REDIRECTS); Charset credentialsCharset = Charset.forName(credentialEncoding); Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create() @@ -275,6 +286,8 @@ final class HttpTransporter extends AbstractTransporter { SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(requestTimeout).build(); RequestConfig requestConfig = RequestConfig.custom() + .setMaxRedirects(maxRedirects) + .setRedirectsEnabled(followRedirects) .setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectTimeout) .setLocalAddress(getBindAddress(session, repository)) @@ -306,6 +319,7 @@ final class HttpTransporter extends AbstractTransporter { HttpClientBuilder builder = HttpClientBuilder.create() .setUserAgent(userAgent) + .setRedirectStrategy(LaxRedirectStrategy.INSTANCE) .setDefaultSocketConfig(socketConfig) .setDefaultRequestConfig(requestConfig) .setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy) @@ -601,7 +615,7 @@ final class HttpTransporter extends AbstractTransporter { } @SuppressWarnings("checkstyle:magicnumber") - private <T extends HttpUriRequest> T resume(T request, GetTask task) { + private <T extends HttpUriRequest> void resume(T request, GetTask task) { long resumeOffset = task.getResumeOffset(); if (resumeOffset > 0L && task.getDataFile() != null) { request.setHeader(HttpHeaders.RANGE, "bytes=" + resumeOffset + '-'); @@ -610,7 +624,6 @@ final class HttpTransporter extends AbstractTransporter { DateUtils.formatDate(new Date(task.getDataFile().lastModified() - 60L * 1000L))); request.setHeader(HttpHeaders.ACCEPT_ENCODING, "identity"); } - return request; } @SuppressWarnings("checkstyle:magicnumber") @@ -787,7 +800,7 @@ final class HttpTransporter extends AbstractTransporter { && (serviceUnavailableHttpCodes.contains( response.getStatusLine().getStatusCode())); if (retry) { - Long retryInterval = retryInterval(response, executionCount, context); + Long retryInterval = retryInterval(response, executionCount); if (retryInterval != null) { RETRY_INTERVAL_HOLDER.set(retryInterval); return true; @@ -804,7 +817,7 @@ final class HttpTransporter extends AbstractTransporter { * * @return Long representing the retry interval as millis, or {@code null} if the request should be failed. */ - private Long retryInterval(HttpResponse httpResponse, int executionCount, HttpContext httpContext) { + private Long retryInterval(HttpResponse httpResponse, int executionCount) { Long result = null; Header header = httpResponse.getFirstHeader(HttpHeaders.RETRY_AFTER); if (header != null && header.getValue() != null) { diff --git a/src/site/markdown/configuration.md b/src/site/markdown/configuration.md index de0168b9..bd8137ce 100644 --- a/src/site/markdown/configuration.md +++ b/src/site/markdown/configuration.md @@ -52,6 +52,8 @@ Option | Type | Description | Default Value | Supports Repo ID Suffix `aether.connector.http.reuseConnections` | boolean | Should HTTP client reuse connections (in other words, pool connections) or not? | `true` | yes `aether.connector.http.supportWebDav` | boolean | If enabled, transport makes best effort to deploy to WebDAV server. This mode is not recommended, better use real Maven Repository Manager instead. | `false` | yes `aether.connector.http.useSystemProperties` | boolean | If enabled, underlying Apache HttpClient will use system properties as well to configure itself (typically used to set up HTTP Proxy via Java system properties). See <a href="https://hc.apache.org/httpcomponents-client-4.5.x/current/httpclient/apidocs/org/apache/http/impl/client/HttpClientBuilder.html">HttpClientBuilder</a> for used properties. This mode is **not recommended**, better use documented ways of configuration instead. | [...] +`aether.connector.http.followRedirects` | boolean | If enabled, the HTTP transport will follow HTTP redirects | `true` | yes +`aether.connector.http.maxRedirects` | int | The max redirect count to follow for the HTTP transport | `5` | yes `aether.connector.https.cipherSuites` | String | Comma-separated list of [Cipher Suites](https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites) which are enabled for HTTPS connections. | - (no restriction) | no `aether.connector.https.securityMode` | String | Using this flag resolver may set the "security mode" of HTTPS connector. Any other mode than 'default' is NOT MEANT for production, as it is inherently not secure. Accepted values: "default", "insecure" (ignore any kind of certificate validation errors and hostname validation checks). | `"default"` | yes `aether.connector.https.protocols` | String | Comma-separated list of [Protocols](https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#jssenames) which are enabled for HTTPS connections. | - (no restriction) | no