HTTPCLIENT-1778: [OSGi] simplify handling of ManagedService based configurations
- simplify TrustedHostsConfiguration handling git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1763263 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e9f8c5b315
commit
71d0567376
|
@ -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<ConnectionSocketFactory> socketFactoryRegistry;
|
||||
|
||||
HttpClientBuilderConfigurator(
|
||||
final BundleContext bundleContext,
|
||||
final List<ProxyConfiguration> proxyConfigurations,
|
||||
final ServiceRegistration<ManagedService> trustedHostsConfiguration) {
|
||||
final TrustedHostsConfiguration trustedHostsConfiguration) {
|
||||
credentialsProvider = new OSGiCredentialsProvider(proxyConfigurations);
|
||||
routePlanner = new OSGiHttpRoutePlanner(proxyConfigurations);
|
||||
socketFactoryRegistry = createSocketFactoryRegistry(bundleContext, trustedHostsConfiguration);
|
||||
socketFactoryRegistry = createSocketFactoryRegistry(trustedHostsConfiguration);
|
||||
}
|
||||
|
||||
<T extends HttpClientBuilder> T configure(final T clientBuilder) {
|
||||
|
@ -67,17 +64,15 @@ final class HttpClientBuilderConfigurator {
|
|||
}
|
||||
|
||||
private Registry<ConnectionSocketFactory> createSocketFactoryRegistry(
|
||||
final BundleContext bundleContext,
|
||||
final ServiceRegistration<ManagedService> trustedHostsConfiguration) {
|
||||
final TrustedHostsConfiguration trustedHostsConfiguration) {
|
||||
return RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.INSTANCE)
|
||||
.register("https", createSocketFactory(bundleContext, trustedHostsConfiguration))
|
||||
.register("https", createSocketFactory(trustedHostsConfiguration))
|
||||
.build();
|
||||
}
|
||||
|
||||
private ConnectionSocketFactory createSocketFactory(
|
||||
final BundleContext bundleContext,
|
||||
final ServiceRegistration<ManagedService> trustedHostsConfiguration) {
|
||||
return new RelaxedLayeredConnectionSocketFactory(bundleContext, trustedHostsConfiguration, getSocketFactory());
|
||||
final TrustedHostsConfiguration trustedHostsConfiguration) {
|
||||
return new RelaxedLayeredConnectionSocketFactory(trustedHostsConfiguration, getSocketFactory());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<ManagedService> trustedHostConfiguration;
|
||||
|
||||
public RelaxedLayeredConnectionSocketFactory(final BundleContext bundleContext,
|
||||
final ServiceRegistration<ManagedService> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String, Object> 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<String, Object> 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<String, Object> 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<String, ?> config) {
|
||||
final ServiceReference<ManagedService> reference = mock(ServiceReference.class);
|
||||
final ServiceRegistration<ManagedService> 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<String, Object> createConfig(final boolean enabled, final boolean trustAll, final String... trustedHosts) {
|
||||
final Dictionary<String, Object> config = new Hashtable<>();
|
||||
config.put("trustedhosts.enabled", enabled);
|
||||
config.put("trustedhosts.trustAll", trustAll);
|
||||
config.put("trustedhosts.hosts", trustedHosts);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue