Issue 342: implemented self-signed cert option for default http service

This commit is contained in:
Adrian Cole 2010-08-20 13:56:05 -07:00
parent 72a0bb58a7
commit df50812b53
6 changed files with 110 additions and 34 deletions

View File

@ -30,21 +30,21 @@ public interface Constants {
* <p/>
* Amount of threads servicing the user requests and transformations
*/
public static final String PROPERTY_USER_THREADS = "jclouds.user_threads";
public static final String PROPERTY_USER_THREADS = "jclouds.user-threads";
/**
* Integer property. default (20)
* <p/>
* Amount of threads servicing the I/O of http connections.
*/
public static final String PROPERTY_IO_WORKER_THREADS = "jclouds.io_worker_threads";
public static final String PROPERTY_IO_WORKER_THREADS = "jclouds.io-worker-threads";
/**
* Integer property. default (20)
* <p/>
* Limits the amount of connections per context.
*/
public static final String PROPERTY_MAX_CONNECTIONS_PER_CONTEXT = "jclouds.max_connections_per_context";
public static final String PROPERTY_MAX_CONNECTIONS_PER_CONTEXT = "jclouds.max-connections-per_context";
/**
* Integer property. default (0)
@ -52,73 +52,73 @@ public interface Constants {
* Limits the amount of connections per host. 0 means indirectly limited by
* {@link #PROPERTY_MAX_CONNECTIONS_PER_CONTEXT}.
*/
public static final String PROPERTY_MAX_CONNECTIONS_PER_HOST = "jclouds.max_connections_per_host";
public static final String PROPERTY_MAX_CONNECTIONS_PER_HOST = "jclouds.max-connections-per-host";
/**
* Integer property. default (2)
* <p/>
* Maximum amount of http session failures before a pool is disabled.
*/
public static final String PROPERTY_MAX_SESSION_FAILURES = "jclouds.max_session_failures";
public static final String PROPERTY_MAX_SESSION_FAILURES = "jclouds.max-session-failures";
/**
* Integer property. default (75)
* <p/>
* Maximum amount of times to re_use an http connection. Services like Amazon S3 throw errors if
* connections are reused too many times.
*/
public static final String PROPERTY_MAX_CONNECTION_REUSE = "jclouds.max_connection_reuse";
public static final String PROPERTY_MAX_CONNECTION_REUSE = "jclouds.max-connection-reuse";
/**
* int property. default (60000)
* <p/>
* How many milliseconds to wait before a socket connection times out. 0 means infinity.
*/
public static final String PROPERTY_SO_TIMEOUT = "jclouds.so_timeout";
public static final String PROPERTY_SO_TIMEOUT = "jclouds.so-timeout";
/**
* Long property. default (60000)
* <p/>
* How many milliseconds to wait before a connection times out. 0 means infinity.
*/
public static final String PROPERTY_CONNECTION_TIMEOUT = "jclouds.connection_timeout";
public static final String PROPERTY_CONNECTION_TIMEOUT = "jclouds.connection-timeout";
/**
* Long property. default (60)
* <p/>
* How many seconds to wait before creating a new session
*/
public static final String PROPERTY_SESSION_INTERVAL = "jclouds.session_interval";
public static final String PROPERTY_SESSION_INTERVAL = "jclouds.session-interval";
/**
* Boolean property.
* <p/>
* Whether or not to use the proxy setup from the underlying operating system.
*/
public static final String PROPERTY_PROXY_SYSTEM = "jclouds.use_system_proxy";
public static final String PROPERTY_PROXY_SYSTEM = "jclouds.use-system-proxy";
/**
* String property.
* <p/>
*Explicitly sets the host name of a HTTP proxy server.
*/
public static final String PROPERTY_PROXY_HOST = "jclouds.proxy_host";
public static final String PROPERTY_PROXY_HOST = "jclouds.proxy-host";
/**
* Integer property.
* <p/>
* Explicitly sets the port number of a HTTP proxy server.
*/
public static final String PROPERTY_PROXY_PORT = "jclouds.proxy_port";
public static final String PROPERTY_PROXY_PORT = "jclouds.proxy-port";
/**
* String property.
* <p/>
* Explicitly sets the user name credential for proxy authentication.
*/
public static final String PROPERTY_PROXY_USER = "jclouds.proxy_user";
public static final String PROPERTY_PROXY_USER = "jclouds.proxy-user";
/**
* String property.
* <p/>
* Explicitly sets the password credential for proxy authentication.
*/
public static final String PROPERTY_PROXY_PASSWORD = "jclouds.proxy_password";
public static final String PROPERTY_PROXY_PASSWORD = "jclouds.proxy-password";
/**
* Integer property.
@ -126,26 +126,32 @@ public interface Constants {
* Commands are retried, if the problem on the server side was a resolvable conflict. However,
* the maximum tries of a single command is bounded.
*/
public static final String PROPERTY_MAX_RETRIES = "jclouds.max_retries";
public static final String PROPERTY_MAX_RETRIES = "jclouds.max-retries";
/**
* Integer property.
* <p/>
* Commands are limited to only a certain amount of redirects.
*/
public static final String PROPERTY_MAX_REDIRECTS = "jclouds.max_redirects";
public static final String PROPERTY_MAX_REDIRECTS = "jclouds.max-redirects";
/**
* Long property.
* <p/>
* longest time a single request can take before throwing an exception.
*/
public static final String PROPERTY_REQUEST_TIMEOUT = "jclouds.request_timeout";
public static final String PROPERTY_REQUEST_TIMEOUT = "jclouds.request-timeout";
/**
* Boolean property.
* <p/>
* allow mismatch between hostname and ssl cerificate. Set to true in DNS_based services like
* Amazon S3.
*/
public static final String PROPERTY_RELAX_HOSTNAME = "jclouds.relax_hostname";
public static final String PROPERTY_RELAX_HOSTNAME = "jclouds.relax-hostname";
/**
* Boolean property.
* <p/>
* trust self-signed certs
*/
public static final String PROPERTY_TRUST_ALL_CERTS = "jclouds.trust-all-certs";
/**
* Name of the logger that records all http headers from the client and the server.
*/
@ -161,7 +167,7 @@ public interface Constants {
/**
* Name of the custom adapter bindings map for Json
*/
public static final String PROPERTY_GSON_ADAPTERS = "jclouds.gson_adapters";
public static final String PROPERTY_GSON_ADAPTERS = "jclouds.gson-adapters";
/**
* String property.
@ -182,7 +188,7 @@ public interface Constants {
* <p/>
* Explicitly identifies the version of an api.
*/
public static final String PROPERTY_API_VERSION = "jclouds.api_version";
public static final String PROPERTY_API_VERSION = "jclouds.api-version";
/**
* String property.

View File

@ -23,6 +23,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_CONNECTION_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS;
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT;
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST;
@ -30,7 +31,6 @@ import static org.jclouds.Constants.PROPERTY_MAX_CONNECTION_REUSE;
import static org.jclouds.Constants.PROPERTY_MAX_REDIRECTS;
import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
import static org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_PROVIDER;
import static org.jclouds.Constants.PROPERTY_PROXY_HOST;
import static org.jclouds.Constants.PROPERTY_PROXY_PASSWORD;
@ -40,6 +40,7 @@ import static org.jclouds.Constants.PROPERTY_PROXY_USER;
import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS;
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import java.util.Properties;
@ -63,6 +64,14 @@ public class PropertiesBuilder {
return this;
}
/**
* @see org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS
*/
public PropertiesBuilder trustAllCerts(boolean trust) {
properties.setProperty(PROPERTY_TRUST_ALL_CERTS, trust + "");
return this;
}
/**
* @see org.jclouds.Constants.PROPERTY_PROXY_SYSTEM
*/
@ -147,8 +156,7 @@ public class PropertiesBuilder {
* @see org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES
*/
public PropertiesBuilder withMaxSessionFailures(int poolMaxSessionFailures) {
properties.setProperty(PROPERTY_MAX_SESSION_FAILURES, Integer
.toString(poolMaxSessionFailures));
properties.setProperty(PROPERTY_MAX_SESSION_FAILURES, Integer.toString(poolMaxSessionFailures));
return this;
}
@ -173,8 +181,7 @@ public class PropertiesBuilder {
* @see org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT
*/
public PropertiesBuilder limitConnectionsTo(int connectionLimit) {
properties.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, Integer
.toString(connectionLimit));
properties.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, Integer.toString(connectionLimit));
return this;
}

View File

@ -117,6 +117,9 @@ public class HttpUtils {
@Inject(optional = true)
@Named(Constants.PROPERTY_PROXY_PASSWORD)
private String proxyPassword;
@Inject(optional = true)
@Named(Constants.PROPERTY_TRUST_ALL_CERTS)
private boolean trustAllCerts;
@Inject
public HttpUtils(@Named(Constants.PROPERTY_CONNECTION_TIMEOUT) int connectionTimeout,
@ -169,6 +172,10 @@ public class HttpUtils {
return relaxHostname;
}
public boolean trustAllCerts() {
return trustAllCerts;
}
public boolean useSystemProxies() {
return systemProxies;
}

View File

@ -19,12 +19,20 @@
package org.jclouds.http.config;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.TransformingHttpCommandExecutorService;
@ -34,6 +42,7 @@ import org.jclouds.logging.Logger;
import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes;
/**
@ -52,11 +61,10 @@ public class JavaUrlHttpCommandExecutorServiceModule extends AbstractModule {
}
protected void bindClient() {
bind(HttpCommandExecutorService.class).to(JavaUrlHttpCommandExecutorService.class).in(
Scopes.SINGLETON);
bind(HttpCommandExecutorService.class).to(JavaUrlHttpCommandExecutorService.class).in(Scopes.SINGLETON);
bind(HostnameVerifier.class).to(LogToMapHostnameVerifier.class);
bind(TransformingHttpCommandExecutorService.class).to(
TransformingHttpCommandExecutorServiceImpl.class).in(Scopes.SINGLETON);
bind(TransformingHttpCommandExecutorService.class).to(TransformingHttpCommandExecutorServiceImpl.class).in(
Scopes.SINGLETON);
}
/**
@ -77,4 +85,35 @@ public class JavaUrlHttpCommandExecutorServiceModule extends AbstractModule {
return true;
}
}
@Provides
@Singleton
@Named("untrusted")
SSLContext provideUntrustedSSLContext(TrustAllCerts trustAllCerts) throws NoSuchAlgorithmException,
KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { trustAllCerts }, new SecureRandom());
return sc;
}
/**
*
* Used to trust all certs
*
* @author Adrian Cole
*/
@Singleton
static class TrustAllCerts implements X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
return;
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
return;
}
}
}

View File

@ -44,9 +44,11 @@ import java.util.concurrent.ExecutorService;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.ws.rs.core.HttpHeaders;
import org.jclouds.Constants;
@ -77,6 +79,7 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
public static final String USER_AGENT = "jclouds/1.0 java/" + System.getProperty("java.version");
@Resource
protected Logger logger = Logger.NULL;
private final Provider<SSLContext> untrustedSSLContextProvider;
private final HostnameVerifier verifier;
private final Field methodField;
@ -84,11 +87,13 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
public JavaUrlHttpCommandExecutorService(HttpUtils utils,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, HostnameVerifier verifier) throws SecurityException,
DelegatingErrorHandler errorHandler, HttpWire wire, HostnameVerifier verifier,
@Named("untrusted") Provider<SSLContext> untrustedSSLContextProvider) throws SecurityException,
NoSuchFieldException {
super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
if (utils.getMaxConnections() > 0)
System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections()));
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
this.verifier = checkNotNull(verifier, "verifier");
this.methodField = HttpURLConnection.class.getDeclaredField("method");
methodField.setAccessible(true);
@ -160,9 +165,12 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
} else {
connection = (HttpURLConnection) url.openConnection();
}
if (utils.relaxHostname() && connection instanceof HttpsURLConnection) {
if (connection instanceof HttpsURLConnection) {
HttpsURLConnection sslCon = (HttpsURLConnection) connection;
sslCon.setHostnameVerifier(verifier);
if (utils.relaxHostname())
sslCon.setHostnameVerifier(verifier);
if (utils.trustAllCerts())
sslCon.setSSLSocketFactory(untrustedSSLContextProvider.get().getSocketFactory());
}
connection.setDoOutput(true);
connection.setAllowUserInteraction(false);

View File

@ -31,6 +31,7 @@ import java.util.concurrent.Executors;
import javax.inject.Provider;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.ws.rs.core.UriBuilder;
@ -112,12 +113,20 @@ public class BackoffLimitedRetryHandlerTest {
RedirectionRetryHandler retry = new RedirectionRetryHandler(uriBuilderProvider, backoff);
JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService(utils, execService,
new DelegatingRetryHandler(backoff, retry), new BackoffLimitedRetryHandler(),
new DelegatingErrorHandler(), new HttpWire(), new HostnameVerifier(){
new DelegatingErrorHandler(), new HttpWire(), new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return false;
}});
}
}, new Provider<SSLContext>() {
@Override
public SSLContext get() {
return null;
}
});
executorService = new TransformingHttpCommandExecutorServiceImpl(httpService, execService);
}