diff --git a/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpClientBuilderConfigurator.java b/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpClientBuilderConfigurator.java index 5492ff85a..bb5d862a9 100644 --- a/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpClientBuilderConfigurator.java +++ b/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpClientBuilderConfigurator.java @@ -31,13 +31,11 @@ import java.util.List; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.sync.HttpClientBuilder; import org.apache.hc.client5.http.osgi.services.ProxyConfiguration; +import org.apache.hc.client5.http.osgi.services.TrustedHostsConfiguration; import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; import org.apache.hc.core5.http.config.Registry; import org.apache.hc.core5.http.config.RegistryBuilder; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; -import org.osgi.service.cm.ManagedService; import static org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory.getSocketFactory; @@ -50,12 +48,11 @@ final class HttpClientBuilderConfigurator { private final Registry socketFactoryRegistry; HttpClientBuilderConfigurator( - final BundleContext bundleContext, final List proxyConfigurations, - final ServiceRegistration trustedHostsConfiguration) { + final TrustedHostsConfiguration trustedHostsConfiguration) { credentialsProvider = new OSGiCredentialsProvider(proxyConfigurations); routePlanner = new OSGiHttpRoutePlanner(proxyConfigurations); - socketFactoryRegistry = createSocketFactoryRegistry(bundleContext, trustedHostsConfiguration); + socketFactoryRegistry = createSocketFactoryRegistry(trustedHostsConfiguration); } T configure(final T clientBuilder) { @@ -67,17 +64,15 @@ final class HttpClientBuilderConfigurator { } private Registry createSocketFactoryRegistry( - final BundleContext bundleContext, - final ServiceRegistration trustedHostsConfiguration) { + final TrustedHostsConfiguration trustedHostsConfiguration) { return RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.INSTANCE) - .register("https", createSocketFactory(bundleContext, trustedHostsConfiguration)) + .register("https", createSocketFactory(trustedHostsConfiguration)) .build(); } private ConnectionSocketFactory createSocketFactory( - final BundleContext bundleContext, - final ServiceRegistration trustedHostsConfiguration) { - return new RelaxedLayeredConnectionSocketFactory(bundleContext, trustedHostsConfiguration, getSocketFactory()); + final TrustedHostsConfiguration trustedHostsConfiguration) { + return new RelaxedLayeredConnectionSocketFactory(trustedHostsConfiguration, getSocketFactory()); } } diff --git a/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpProxyConfigurationActivator.java b/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpProxyConfigurationActivator.java index 67795bbfb..0d943eb09 100644 --- a/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpProxyConfigurationActivator.java +++ b/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/HttpProxyConfigurationActivator.java @@ -108,12 +108,11 @@ public final class HttpProxyConfigurationActivator implements BundleActivator, M props.put(Constants.SERVICE_PID, TRUSTED_HOSTS_PID); props.put(Constants.SERVICE_VENDOR, context.getBundle().getHeaders().get(Constants.BUNDLE_VENDOR)); props.put(Constants.SERVICE_DESCRIPTION, TRUSTED_HOSTS_SERVICE_NAME); - trustedHostConfiguration = context.registerService(ManagedService.class, - new OSGiTrustedHostsConfiguration(), - props); + final OSGiTrustedHostsConfiguration trustedHosts = new OSGiTrustedHostsConfiguration(); + trustedHostConfiguration = context.registerService(ManagedService.class, trustedHosts, props); final HttpClientBuilderConfigurator configurator = - new HttpClientBuilderConfigurator(context, proxyConfigurations, trustedHostConfiguration); + new HttpClientBuilderConfigurator(proxyConfigurations, trustedHosts); props.clear(); props.put(Constants.SERVICE_PID, BUILDER_FACTORY_SERVICE_PID); diff --git a/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/RelaxedLayeredConnectionSocketFactory.java b/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/RelaxedLayeredConnectionSocketFactory.java index cd02dad8c..ff854d7d4 100644 --- a/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/RelaxedLayeredConnectionSocketFactory.java +++ b/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/RelaxedLayeredConnectionSocketFactory.java @@ -36,23 +36,16 @@ import org.apache.hc.client5.http.osgi.services.TrustedHostsConfiguration; import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.protocol.HttpContext; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; -import org.osgi.service.cm.ManagedService; final class RelaxedLayeredConnectionSocketFactory implements LayeredConnectionSocketFactory { + private TrustedHostsConfiguration trustedHostsConfiguration; + private final LayeredConnectionSocketFactory defaultSocketFactory; - private final BundleContext bundleContext; - - private final ServiceRegistration trustedHostConfiguration; - - public RelaxedLayeredConnectionSocketFactory(final BundleContext bundleContext, - final ServiceRegistration trustedHostConfiguration, + public RelaxedLayeredConnectionSocketFactory(final TrustedHostsConfiguration trustedHostsConfiguration, final LayeredConnectionSocketFactory defaultSocketFactory) { - this.bundleContext = bundleContext; - this.trustedHostConfiguration = trustedHostConfiguration; + this.trustedHostsConfiguration = trustedHostsConfiguration; this.defaultSocketFactory = defaultSocketFactory; } @@ -61,26 +54,21 @@ final class RelaxedLayeredConnectionSocketFactory implements LayeredConnectionSo final String target, final int port, final HttpContext context) throws IOException { - final ManagedService trustedHostsConfigurationObject = bundleContext.getService(trustedHostConfiguration.getReference()); - if (trustedHostsConfigurationObject != null) { - final TrustedHostsConfiguration configuration = (TrustedHostsConfiguration) trustedHostsConfigurationObject; + if (trustedHostsConfiguration.isEnabled()) { + // if trust all there is no check to perform + if (trustedHostsConfiguration.trustAll()) { + return socket; + } - if (configuration.isEnabled()) { - // if trust all there is no check to perform - if (configuration.trustAll()) { + // blindly verify the host if in the trust list + for (String trustedHost : trustedHostsConfiguration.getTrustedHosts()) { + if (createMatcher(trustedHost).matches(target)) { return socket; } - - // blindly verify the host if in the trust list - for (String trustedHost : configuration.getTrustedHosts()) { - if (createMatcher(trustedHost).matches(target)) { - return socket; - } - } } } - // follow back to the default behavior + // fall back to the default behavior return defaultSocketFactory.createLayeredSocket(socket, target, port, context); } diff --git a/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/TestRelaxedLayeredConnectionSocketFactory.java b/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/TestRelaxedLayeredConnectionSocketFactory.java index ec40a90c1..6bd5214ba 100644 --- a/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/TestRelaxedLayeredConnectionSocketFactory.java +++ b/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/TestRelaxedLayeredConnectionSocketFactory.java @@ -26,10 +26,7 @@ */ package org.apache.hc.client5.http.osgi.impl; -import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import java.io.IOException; import java.net.InetSocketAddress; @@ -42,79 +39,56 @@ import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.protocol.BasicHttpContext; import org.apache.hc.core5.http.protocol.HttpContext; import org.junit.Test; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; +import org.mockito.Mock; import org.osgi.service.cm.ConfigurationException; -import org.osgi.service.cm.ManagedService; public class TestRelaxedLayeredConnectionSocketFactory { + @Mock + Socket insecureSocket; + + @Mock + Socket secureSocket; + + private final HttpContext context = new BasicHttpContext(); + @Test public void testTrustedAllConnections() throws Exception { - final HttpContext context = new BasicHttpContext(); - - final Dictionary config = new Hashtable<>(); - config.put("trustedhosts.enabled", Boolean.TRUE); - config.put("trustedhosts.trustAll", Boolean.TRUE); - config.put("trustedhosts.hosts", new String[]{}); - final LayeredConnectionSocketFactory socketFactory = getLayeredConnectionSocketFactory(config); + final LayeredConnectionSocketFactory socketFactory = getLayeredConnectionSocketFactory(true, true); final Socket socket = socketFactory.createSocket(context); final Socket secureSocket = socketFactory.createLayeredSocket(socket, "localhost", 9999, context); - assertSame(socket, secureSocket); + assertSame(this.secureSocket, secureSocket); } @Test public void testTrustedConnections() throws Exception { - final HttpContext context = new BasicHttpContext(); - final Dictionary config = new Hashtable<>(); - config.put("trustedhosts.enabled", Boolean.TRUE); - config.put("trustedhosts.trustAll", Boolean.FALSE); - config.put("trustedhosts.hosts", new String[]{ "localhost" }); - final LayeredConnectionSocketFactory socketFactory = getLayeredConnectionSocketFactory(config); - + final LayeredConnectionSocketFactory socketFactory = getLayeredConnectionSocketFactory(true, false, "localhost"); final Socket socket = socketFactory.createSocket(context); final Socket localSecureSocket = socketFactory.createLayeredSocket(socket, "localhost", 9999, context); - assertSame(socket, localSecureSocket); + assertSame(this.insecureSocket, localSecureSocket); final Socket apacheSecureSocket = socketFactory.createLayeredSocket(socket, "www.apache.org", 9999, context); - assertNotSame(socket, apacheSecureSocket); + assertSame(this.secureSocket, apacheSecureSocket); } @Test public void testNotEabledConfiguration() throws Exception { - final HttpContext context = new BasicHttpContext(); - - final Dictionary config = new Hashtable<>(); - config.put("trustedhosts.enabled", Boolean.TRUE); - config.put("trustedhosts.trustAll", Boolean.FALSE); - config.put("trustedhosts.hosts", new String[]{}); - final LayeredConnectionSocketFactory socketFactory = getLayeredConnectionSocketFactory(config); + final LayeredConnectionSocketFactory socketFactory = getLayeredConnectionSocketFactory(false, true); final Socket socket = socketFactory.createSocket(context); final Socket secureSocket = socketFactory.createLayeredSocket(socket, "localhost", 9999, context); - assertNotSame(socket, secureSocket); + assertSame(this.secureSocket, secureSocket); } - private LayeredConnectionSocketFactory getLayeredConnectionSocketFactory(final Dictionary config) { - final ServiceReference reference = mock(ServiceReference.class); - final ServiceRegistration registration = mock(ServiceRegistration.class); - when(registration.getReference()).thenReturn(reference); - final BundleContext bundleContext = mock(BundleContext.class); + private LayeredConnectionSocketFactory getLayeredConnectionSocketFactory( + final boolean enabled, final boolean trustAll, final String... trustedHosts) throws ConfigurationException { final OSGiTrustedHostsConfiguration configuration = new OSGiTrustedHostsConfiguration(); - try { - configuration.updated(config); - } catch (ConfigurationException e) { - // it doesn't happen in tests - } - when(bundleContext.getService(reference)).thenReturn(configuration); + configuration.updated(createConfig(enabled, trustAll, trustedHosts)); - final Socket socket = mock(Socket.class); - final Socket secureSocket = mock(Socket.class); final LayeredConnectionSocketFactory defaultSocketFactory = new LayeredConnectionSocketFactory() { @Override public Socket createSocket(final HttpContext context) throws IOException { - return socket; + return insecureSocket; } @Override @@ -125,7 +99,7 @@ public class TestRelaxedLayeredConnectionSocketFactory { final InetSocketAddress localAddress, final HttpContext context ) throws IOException { // not needed in this version - return socket; + return insecureSocket; } @Override @@ -138,7 +112,15 @@ public class TestRelaxedLayeredConnectionSocketFactory { }; - return new RelaxedLayeredConnectionSocketFactory(bundleContext, registration, defaultSocketFactory); + return new RelaxedLayeredConnectionSocketFactory(configuration, defaultSocketFactory); + } + + private Dictionary createConfig(final boolean enabled, final boolean trustAll, final String... trustedHosts) { + final Dictionary config = new Hashtable<>(); + config.put("trustedhosts.enabled", enabled); + config.put("trustedhosts.trustAll", trustAll); + config.put("trustedhosts.hosts", trustedHosts); + return config; } }