Skip to content

Commit

Permalink
fix: socketfactory not registered for apache (#1637)
Browse files Browse the repository at this point in the history
* fix: socketfactory not registered for apache

* refactor code and add test
  • Loading branch information
arithmetic1728 committed Nov 16, 2020
1 parent a14925f commit e886efa
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 31 deletions.
Expand Up @@ -21,14 +21,19 @@
import com.google.api.client.http.apache.v2.ApacheHttpTransport;
import com.google.api.client.util.Beta;
import com.google.api.client.util.SslUtils;
import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.net.ProxySelector;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
Expand Down Expand Up @@ -64,50 +69,75 @@ public static ApacheHttpTransport newTrustedTransport()
@Beta
public static ApacheHttpTransport newTrustedTransport(MtlsProvider mtlsProvider)
throws GeneralSecurityException, IOException {
KeyStore mtlsKeyStore = null;
String mtlsKeyStorePassword = null;
if (mtlsProvider.useMtlsClientCertificate()) {
mtlsKeyStore = mtlsProvider.getKeyStore();
mtlsKeyStorePassword = mtlsProvider.getKeyStorePassword();
}

SocketFactoryRegistryHandler handler = new SocketFactoryRegistryHandler(mtlsProvider);
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(-1, TimeUnit.MILLISECONDS);
new PoolingHttpClientConnectionManager(
handler.getSocketFactoryRegistry(), null, null, null, -1, TimeUnit.MILLISECONDS);

// Disable the stale connection check (previously configured in the HttpConnectionParams
// Disable the stale connection check (previously configured in the
// HttpConnectionParams
connectionManager.setValidateAfterInactivity(-1);

// Use the included trust store
KeyStore trustStore = GoogleUtils.getCertificateTrustStore();
SSLContext sslContext = SslUtils.getTlsSslContext();

boolean isMtls = false;
if (mtlsKeyStore != null && mtlsKeyStorePassword != null) {
isMtls = true;
SslUtils.initSslContext(
sslContext,
trustStore,
SslUtils.getPkixTrustManagerFactory(),
mtlsKeyStore,
mtlsKeyStorePassword,
SslUtils.getDefaultKeyManagerFactory());
} else {
SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory());
}
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);

HttpClient client =
HttpClientBuilder.create()
.useSystemProperties()
.setSSLSocketFactory(socketFactory)
.setMaxConnTotal(200)
.setMaxConnPerRoute(20)
.setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault()))
.setConnectionManager(connectionManager)
.disableRedirectHandling()
.disableAutomaticRetries()
.build();
return new ApacheHttpTransport(client, isMtls);
return new ApacheHttpTransport(client, handler.isMtls());
}

@VisibleForTesting
static class SocketFactoryRegistryHandler {
private final Registry<ConnectionSocketFactory> socketFactoryRegistry;
private final boolean isMtls;

public SocketFactoryRegistryHandler(MtlsProvider mtlsProvider)
throws GeneralSecurityException, IOException {
KeyStore mtlsKeyStore = null;
String mtlsKeyStorePassword = null;
if (mtlsProvider.useMtlsClientCertificate()) {
mtlsKeyStore = mtlsProvider.getKeyStore();
mtlsKeyStorePassword = mtlsProvider.getKeyStorePassword();
}

// Use the included trust store
KeyStore trustStore = GoogleUtils.getCertificateTrustStore();
SSLContext sslContext = SslUtils.getTlsSslContext();

if (mtlsKeyStore != null && mtlsKeyStorePassword != null) {
this.isMtls = true;
SslUtils.initSslContext(
sslContext,
trustStore,
SslUtils.getPkixTrustManagerFactory(),
mtlsKeyStore,
mtlsKeyStorePassword,
SslUtils.getDefaultKeyManagerFactory());
} else {
this.isMtls = false;
SslUtils.initSslContext(sslContext, trustStore, SslUtils.getPkixTrustManagerFactory());
}
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);

this.socketFactoryRegistry =
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", socketFactory)
.build();
}

public Registry<ConnectionSocketFactory> getSocketFactoryRegistry() {
return this.socketFactoryRegistry;
}

public boolean isMtls() {
return this.isMtls;
}
}

private GoogleApacheHttpTransport() {}
Expand Down
Expand Up @@ -14,16 +14,30 @@

package com.google.api.client.googleapis.apache.v2;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.google.api.client.googleapis.apache.v2.GoogleApacheHttpTransport.SocketFactoryRegistryHandler;
import com.google.api.client.googleapis.mtls.MtlsProvider;
import com.google.api.client.googleapis.mtls.MtlsTransportBaseTest;
import com.google.api.client.http.HttpTransport;
import java.io.IOException;
import java.security.GeneralSecurityException;
import org.junit.Test;

public class GoogleApacheHttpTransportTest extends MtlsTransportBaseTest {
@Override
protected HttpTransport buildTrustedTransport(MtlsProvider mtlsProvider)
throws GeneralSecurityException, IOException {
return GoogleApacheHttpTransport.newTrustedTransport(mtlsProvider);
}

@Test
public void socketFactoryRegistryHandlerTest() throws GeneralSecurityException, IOException {
MtlsProvider mtlsProvider = new TestMtlsProvider(true, createTestMtlsKeyStore(), "", false);
SocketFactoryRegistryHandler handler = new SocketFactoryRegistryHandler(mtlsProvider);
assertNotNull(handler.getSocketFactoryRegistry().lookup("http"));
assertNotNull(handler.getSocketFactoryRegistry().lookup("https"));
assertTrue(handler.isMtls());
}
}
Expand Up @@ -41,7 +41,7 @@ protected static class TestMtlsProvider implements MtlsProvider {
private String keyStorePassword;
private boolean throwExceptionForGetKeyStore;

TestMtlsProvider(
public TestMtlsProvider(
boolean useClientCertificate,
KeyStore keystore,
String keyStorePassword,
Expand Down

0 comments on commit e886efa

Please sign in to comment.