Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=402740
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/META-INF/MANIFEST.MF b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/META-INF/MANIFEST.MF
index 1d64634..5c54c11 100644
--- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/META-INF/MANIFEST.MF
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %plugin.name
Bundle-SymbolicName: org.eclipse.ecf.provider.filetransfer.httpclient4;singleton:=true
-Bundle-Version: 1.0.200.qualifier
+Bundle-Version: 1.0.300.qualifier
Bundle-Localization: plugin
Bundle-Activator: org.eclipse.ecf.internal.provider.filetransfer.httpclient4.Activator
Require-Bundle: org.eclipse.equinox.common,
diff --git a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient4/HttpClientProxyCredentialProvider.java b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient4/HttpClientProxyCredentialProvider.java
index e8407f8..56868d0 100644
--- a/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient4/HttpClientProxyCredentialProvider.java
+++ b/providers/bundles/org.eclipse.ecf.provider.filetransfer.httpclient4/src/org/eclipse/ecf/internal/provider/filetransfer/httpclient4/HttpClientProxyCredentialProvider.java
@@ -11,13 +11,14 @@
*******************************************************************************/
package org.eclipse.ecf.internal.provider.filetransfer.httpclient4;
-import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.eclipse.ecf.core.util.Proxy;
+import org.eclipse.ecf.core.util.ProxyAddress;
import org.eclipse.ecf.core.util.Trace;
public abstract class HttpClientProxyCredentialProvider implements CredentialsProvider {
@@ -29,25 +30,34 @@
private Map cachedCredentials;
public HttpClientProxyCredentialProvider() {
- cachedCredentials = new HashMap();
+ cachedCredentials = new ConcurrentHashMap<AuthScope, Credentials>();
}
public void setCredentials(AuthScope authscope, Credentials credentials) {
+ if (authscope == null)
+ throw new IllegalArgumentException("Authentication scope may not be null"); //$NON-NLS-1$
this.cachedCredentials.put(authscope, credentials);
}
public Credentials getCredentials(AuthScope authscope) {
Trace.entering(Activator.PLUGIN_ID, DebugOptions.METHODS_ENTERING, HttpClientProxyCredentialProvider.class, "getCredentials " + authscope); //$NON-NLS-1$
- if (this.cachedCredentials.containsKey(authscope)) {
- return (Credentials) this.cachedCredentials.get(authscope);
- }
-
+ // First check to see whether given authscope matches any authscope
+ // already cached.
+ Credentials result = matchCredentials(this.cachedCredentials, authscope);
+ // If we have a match, return credentials
+ if (result != null)
+ return result;
+ // If we don't have a match, first get ECF proxy, if any
Proxy proxy = getECFProxy();
- if (proxy == null) {
+ if (proxy == null)
return null;
- }
+ // Make sure that authscope and proxy host and port match
+ if (!matchAuthScopeAndProxy(authscope, proxy))
+ return null;
+
+ // Then match scheme, and get credentials from proxy (if it's scheme we know about)
Credentials credentials = null;
if ("ntlm".equalsIgnoreCase(authscope.getScheme())) { //$NON-NLS-1$
credentials = getNTLMCredentials(proxy);
@@ -55,6 +65,7 @@
"digest".equalsIgnoreCase(authscope.getScheme())) { //$NON-NLS-1$
final String proxyUsername = proxy.getUsername();
final String proxyPassword = proxy.getPassword();
+ // If credentials present for proxy then we're done
if (proxyUsername != null) {
credentials = new UsernamePasswordCredentials(proxyUsername, proxyPassword);
}
@@ -64,13 +75,40 @@
Trace.trace(Activator.PLUGIN_ID, "Unrecognized authentication scheme."); //$NON-NLS-1$
}
- if (credentials != null) {
+ // Put found credentials in cache for next time
+ if (credentials != null)
cachedCredentials.put(authscope, credentials);
- }
return credentials;
}
+ private boolean matchAuthScopeAndProxy(AuthScope authscope, Proxy proxy) {
+ ProxyAddress proxyAddress = proxy.getAddress();
+ return (authscope.getHost().equals(proxyAddress.getHostName()) && (authscope.getPort() == proxyAddress.getPort()));
+ }
+
+ private static Credentials matchCredentials(final Map<AuthScope, Credentials> map, final AuthScope authscope) {
+ // see if we get a direct hit
+ Credentials creds = map.get(authscope);
+ if (creds == null) {
+ // Nope.
+ // Do a full scan
+ int bestMatchFactor = -1;
+ AuthScope bestMatch = null;
+ for (AuthScope current : map.keySet()) {
+ int factor = authscope.match(current);
+ if (factor > bestMatchFactor) {
+ bestMatchFactor = factor;
+ bestMatch = current;
+ }
+ }
+ if (bestMatch != null) {
+ creds = map.get(bestMatch);
+ }
+ }
+ return creds;
+ }
+
public void clear() {
this.cachedCredentials.clear();
}