Skip to content

Commit f20d1e3

Browse files
author
Marshall Pierce
committed
Change DefaultSslEngineFactory to lazily build its SslContext, which makes it feasible provide a subclass of DSEF via config that can customize the SslContext as it is built. Let SSLContext errors be detected early by adding init() to SslEngineFactory.
1 parent 33b9f46 commit f20d1e3

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

client/src/main/java/org/asynchttpclient/SslEngineFactory.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.asynchttpclient;
1515

1616
import javax.net.ssl.SSLEngine;
17+
import javax.net.ssl.SSLException;
1718

1819
public interface SslEngineFactory {
1920

@@ -26,4 +27,16 @@ public interface SslEngineFactory {
2627
* @return new engine
2728
*/
2829
SSLEngine newSslEngine(AsyncHttpClientConfig config, String peerHost, int peerPort);
30+
31+
/**
32+
* Perform any necessary one-time configuration. This will be called just once before {@code newSslEngine} is called
33+
* for the first time.
34+
*
35+
* @param config the client config
36+
* @throws SSLException if initialization fails. If an exception is thrown, the instance will not be used as client
37+
* creation will fail.
38+
*/
39+
default void init(AsyncHttpClientConfig config) throws SSLException {
40+
// no op
41+
}
2942
}

client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,11 @@ public class ChannelManager {
111111
public ChannelManager(final AsyncHttpClientConfig config, Timer nettyTimer) {
112112

113113
this.config = config;
114+
this.sslEngineFactory = config.getSslEngineFactory() != null ? config.getSslEngineFactory() : new DefaultSslEngineFactory();
114115
try {
115-
this.sslEngineFactory = config.getSslEngineFactory() != null ? config.getSslEngineFactory() : new DefaultSslEngineFactory(config);
116+
this.sslEngineFactory.init(config);
116117
} catch (SSLException e) {
117-
throw new ExceptionInInitializerError(e);
118+
throw new RuntimeException("Could not initialize sslEngineFactory", e);
118119
}
119120

120121
ChannelPool channelPool = config.getChannelPool();

client/src/main/java/org/asynchttpclient/netty/ssl/DefaultSslEngineFactory.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,9 @@
2626

2727
public class DefaultSslEngineFactory extends SslEngineFactoryBase {
2828

29-
private final SslContext sslContext;
29+
private volatile SslContext sslContext;
3030

31-
public DefaultSslEngineFactory(AsyncHttpClientConfig config) throws SSLException {
32-
this.sslContext = getSslContext(config);
33-
}
34-
35-
private SslContext getSslContext(AsyncHttpClientConfig config) throws SSLException {
31+
private SslContext buildSslContext(AsyncHttpClientConfig config) throws SSLException {
3632
if (config.getSslContext() != null)
3733
return config.getSslContext();
3834

@@ -44,7 +40,7 @@ private SslContext getSslContext(AsyncHttpClientConfig config) throws SSLExcepti
4440
if (config.isAcceptAnyCertificate())
4541
sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
4642

47-
return sslContextBuilder.build();
43+
return configureSslContextBuilder(sslContextBuilder).build();
4844
}
4945

5046
@Override
@@ -54,4 +50,22 @@ public SSLEngine newSslEngine(AsyncHttpClientConfig config, String peerHost, int
5450
configureSslEngine(sslEngine, config);
5551
return sslEngine;
5652
}
53+
54+
@Override
55+
public void init(AsyncHttpClientConfig config) throws SSLException {
56+
sslContext = buildSslContext(config);
57+
}
58+
59+
/**
60+
* The last step of configuring the SslContextBuilder used to create an SslContext when no context is provided in
61+
* the {@link AsyncHttpClientConfig}. This defaults to no-op and is intended to be overridden as needed.
62+
*
63+
* @param builder builder with normal configuration applied
64+
* @return builder to be used to build context (can be the same object as the input)
65+
*/
66+
protected SslContextBuilder configureSslContextBuilder(SslContextBuilder builder) {
67+
// default to no op
68+
return builder;
69+
}
70+
5771
}

0 commit comments

Comments
 (0)