mirror of https://github.com/apache/ant-ivy
Merge a5b82aafd7 into 6546134471
This commit is contained in:
commit
75276b4636
|
|
@ -44,6 +44,8 @@ For details about the following changes, check our JIRA install at link:https://
|
|||
|
||||
Note, if you have resolved dependencies with version of Ivy prior to 2.6.1, you may need to remove your Ivy cache for some fixes to have any effect.
|
||||
|
||||
- IMPROVEMENT: Support link:https://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/authentication.html[preemptive authentication]. (jira:IVY-1280[])
|
||||
|
||||
////
|
||||
Samples :
|
||||
- NEW: bla bla bla (jira:IVY-1234[]) (Thanks to Jane Doe)
|
||||
|
|
@ -150,6 +152,7 @@ Here is the list of people who have contributed source code and documentation up
|
|||
* Antoine Levy-Lambert
|
||||
* Tony Likhite
|
||||
* Andrey Lomakin
|
||||
* Aurélien Lourot
|
||||
* William Lyvers
|
||||
* Sakari Maaranen
|
||||
* David Maplesden
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ So if there is a setting in the resolver, it always wins against all other setti
|
|||
|validate|Indicates if Ivy files should be validated against ivy.xsd or not.|No, defaults to true
|
||||
|useRemoteConfig|true to configure ivyrep and ibiblio resolver from a remote settings file (updated with changes in those repository structure if any) (*__since 1.2__*)|No, defaults to false
|
||||
|httpRequestMethod|specifies the HTTP method to use to retrieve information about an URL. Possible values are 'GET' and 'HEAD'. This setting can be used to solve problems with firewalls and proxies. (*__since 2.0__*)|No, defaults to 'HEAD'
|
||||
|preemptiveAuth|true to use link:https://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/authentication.html[preemptive authentication] whenever possible (only supported with link:https://hc.apache.org/httpcomponents-client-4.5.x[HttpClient] as URL Handler) (*__since 2.5__*)|No, defaults to false
|
||||
|[line-through]#defaultCache#|a path to a directory to use as default basedir for both resolution and repository cache(s). +
|
||||
__Deprecated, we recommend using defaultCacheDir on the link:../settings/caches{outfilesuffix}[caches] tag instead__|No, defaults to .ivy2/cache in user home
|
||||
|[line-through]#checkUpToDate#|Indicates if date should be checked before retrieving artifacts from cache. +
|
||||
|
|
|
|||
|
|
@ -369,6 +369,11 @@ public class XmlSettingsParser extends DefaultHandler {
|
|||
throw new IllegalArgumentException(
|
||||
"Invalid httpRequestMethod specified, must be one of {'HEAD', 'GET'}");
|
||||
}
|
||||
|
||||
String preemptiveAuth = attributes.get("preemptiveAuth");
|
||||
if (preemptiveAuth != null) {
|
||||
URLHandlerRegistry.getHttp().setPreemptiveAuth(Boolean.valueOf(preemptiveAuth));
|
||||
}
|
||||
}
|
||||
|
||||
private void includeStarted(Map<String, String> attributes) throws IOException, ParseException {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ public abstract class AbstractURLHandler implements URLHandler {
|
|||
// the request method to use. TODO: don't use a static here
|
||||
private static int requestMethod = REQUEST_METHOD_HEAD;
|
||||
|
||||
private boolean preemptiveAuth = false;
|
||||
|
||||
@Override
|
||||
public boolean isReachable(final URL url) {
|
||||
return getURLInfo(url).isReachable();
|
||||
|
|
@ -106,6 +108,14 @@ public abstract class AbstractURLHandler implements URLHandler {
|
|||
return requestMethod;
|
||||
}
|
||||
|
||||
public void setPreemptiveAuth(boolean preemptive) {
|
||||
this.preemptiveAuth = preemptive;
|
||||
}
|
||||
|
||||
public boolean getPreemptiveAuth() {
|
||||
return this.preemptiveAuth;
|
||||
}
|
||||
|
||||
protected String normalizeToString(URL url) throws IOException {
|
||||
if (!"http".equals(url.getProtocol()) && !"https".equals(url.getProtocol())) {
|
||||
return url.toExternalForm();
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.ivy.util.url;
|
|||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.auth.AuthSchemeProvider;
|
||||
|
|
@ -26,21 +27,25 @@ import org.apache.http.auth.AuthScope;
|
|||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.NTCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.config.AuthSchemes;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.config.Lookup;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.conn.routing.HttpRoutePlanner;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.FileEntity;
|
||||
import org.apache.http.impl.auth.BasicScheme;
|
||||
import org.apache.http.impl.auth.BasicSchemeFactory;
|
||||
import org.apache.http.impl.auth.DigestSchemeFactory;
|
||||
import org.apache.http.impl.auth.NTLMSchemeFactory;
|
||||
import org.apache.http.impl.client.BasicAuthCache;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
|
|
@ -186,7 +191,7 @@ public class HttpClientHandler extends AbstractURLHandler implements TimeoutCons
|
|||
final HttpPut put = new HttpPut(normalizeToString(dest));
|
||||
put.setConfig(requestConfig);
|
||||
put.setEntity(new FileEntity(src));
|
||||
try (final CloseableHttpResponse response = this.httpClient.execute(put)) {
|
||||
try (final CloseableHttpResponse response = this.httpClient.execute(put, getHttpClientContext(dest))) {
|
||||
validatePutStatusCode(dest, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase());
|
||||
}
|
||||
}
|
||||
|
|
@ -333,7 +338,7 @@ public class HttpClientHandler extends AbstractURLHandler implements TimeoutCons
|
|||
final HttpGet httpGet = new HttpGet(normalizeToString(url));
|
||||
httpGet.setConfig(requestConfig);
|
||||
httpGet.addHeader("Accept-Encoding", "gzip,deflate");
|
||||
return this.httpClient.execute(httpGet);
|
||||
return this.httpClient.execute(httpGet, getHttpClientContext(url));
|
||||
}
|
||||
|
||||
private CloseableHttpResponse doHead(final URL url, final int connectionTimeout, final int readTimeout) throws IOException {
|
||||
|
|
@ -345,13 +350,34 @@ public class HttpClientHandler extends AbstractURLHandler implements TimeoutCons
|
|||
.build();
|
||||
final HttpHead httpHead = new HttpHead(normalizeToString(url));
|
||||
httpHead.setConfig(requestConfig);
|
||||
return this.httpClient.execute(httpHead);
|
||||
return this.httpClient.execute(httpHead, getHttpClientContext(url));
|
||||
}
|
||||
|
||||
private boolean hasCredentialsConfigured(final URL url) {
|
||||
return CredentialsStore.INSTANCE.hasCredentials(url.getHost());
|
||||
}
|
||||
|
||||
private HttpClientContext getHttpClientContext(URL dest) {
|
||||
if (!getPreemptiveAuth()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Preemptive authentication, see
|
||||
// https://hc.apache.org/httpcomponents-client-4.5.x/tutorial/html/authentication.html
|
||||
// Without preemptive authentication, Ivy will first try non-authenticated, get a 4xx, retry
|
||||
// authenticated and finally get a 2xx. This becomes an issue in an environment where Ivy is
|
||||
// used a lot, as firewalls might see large amounts of 4xx as a brute-force attack and close
|
||||
// the connections.
|
||||
|
||||
final BasicScheme basicAuth = new BasicScheme();
|
||||
final HttpHost target = new HttpHost(dest.getHost(), dest.getPort(), dest.getProtocol());
|
||||
final AuthCache authCache = new BasicAuthCache();
|
||||
authCache.put(target, basicAuth);
|
||||
final HttpClientContext localContext = HttpClientContext.create();
|
||||
localContext.setAuthCache(authCache);
|
||||
return localContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
if (this.httpClient != null) {
|
||||
|
|
|
|||
|
|
@ -126,4 +126,12 @@ public interface TimeoutConstrainedURLHandler extends URLHandler {
|
|||
* @since 2.5
|
||||
*/
|
||||
void upload(File src, URL dest, CopyProgressListener listener, TimeoutConstraint timeoutConstraint) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the flag enabling or disabling preemptive authentication.
|
||||
*
|
||||
* @param preemptive The flag
|
||||
* @since 2.6
|
||||
*/
|
||||
void setPreemptiveAuth(boolean preemptive);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,6 +179,15 @@ public class URLHandlerDispatcher implements TimeoutConstrainedURLHandler {
|
|||
}
|
||||
}
|
||||
|
||||
public void setPreemptiveAuth(boolean preemptive) {
|
||||
((TimeoutConstrainedURLHandler) defaultHandler).setPreemptiveAuth(preemptive);
|
||||
for (URLHandler handler : handlers.values()) {
|
||||
if (handler instanceof TimeoutConstrainedURLHandler) {
|
||||
((TimeoutConstrainedURLHandler) handler).setPreemptiveAuth(preemptive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setDownloader(String protocol, URLHandler downloader) {
|
||||
handlers.put(protocol, downloader);
|
||||
|
|
|
|||
Loading…
Reference in New Issue