Skip to content

Commit 8293c6b

Browse files
committed
Make REST Client work whether or not SSL is enabled or not in native
This is done in order to enable the use of Apache HTTP Client in all cases where the REST Client is used. This enables us to drop the fallback to URLConnection which is rather limited Fixes: #9342
1 parent 4c82851 commit 8293c6b

File tree

6 files changed

+116
-143
lines changed

6 files changed

+116
-143
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package io.quarkus.runtime.graal;
2+
3+
import java.io.IOException;
4+
import java.net.InetAddress;
5+
import java.net.Socket;
6+
import java.net.UnknownHostException;
7+
import java.security.KeyManagementException;
8+
import java.security.Provider;
9+
import java.security.SecureRandom;
10+
11+
import javax.net.ssl.KeyManager;
12+
import javax.net.ssl.SSLContext;
13+
import javax.net.ssl.SSLContextSpi;
14+
import javax.net.ssl.SSLEngine;
15+
import javax.net.ssl.SSLServerSocketFactory;
16+
import javax.net.ssl.SSLSessionContext;
17+
import javax.net.ssl.SSLSocketFactory;
18+
import javax.net.ssl.TrustManager;
19+
20+
public class DisabledSSLContext extends SSLContext {
21+
22+
public DisabledSSLContext() {
23+
super(new DisabledSSLContextSpi(), new Provider("DISABLED", 1, "DISABLED") {
24+
}, "DISABLED");
25+
}
26+
27+
private static class DisabledSSLContextSpi extends SSLContextSpi {
28+
29+
@Override
30+
protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers, SecureRandom secureRandom)
31+
throws KeyManagementException {
32+
}
33+
34+
@Override
35+
protected SSLSocketFactory engineGetSocketFactory() {
36+
return new SSLSocketFactory() {
37+
@Override
38+
public String[] getDefaultCipherSuites() {
39+
return new String[0];
40+
}
41+
42+
@Override
43+
public String[] getSupportedCipherSuites() {
44+
return new String[0];
45+
}
46+
47+
@Override
48+
public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
49+
throw sslSupportDisabledException();
50+
}
51+
52+
@Override
53+
public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
54+
throw sslSupportDisabledException();
55+
}
56+
57+
@Override
58+
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1)
59+
throws IOException, UnknownHostException {
60+
throw sslSupportDisabledException();
61+
}
62+
63+
@Override
64+
public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
65+
throw sslSupportDisabledException();
66+
}
67+
68+
@Override
69+
public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1)
70+
throws IOException {
71+
throw sslSupportDisabledException();
72+
}
73+
};
74+
}
75+
76+
@Override
77+
protected SSLServerSocketFactory engineGetServerSocketFactory() {
78+
throw sslSupportDisabledException();
79+
}
80+
81+
@Override
82+
protected SSLEngine engineCreateSSLEngine() {
83+
throw sslSupportDisabledException();
84+
}
85+
86+
@Override
87+
protected SSLEngine engineCreateSSLEngine(String s, int i) {
88+
throw sslSupportDisabledException();
89+
}
90+
91+
@Override
92+
protected SSLSessionContext engineGetServerSessionContext() {
93+
throw sslSupportDisabledException();
94+
}
95+
96+
@Override
97+
protected SSLSessionContext engineGetClientSessionContext() {
98+
throw sslSupportDisabledException();
99+
}
100+
101+
private RuntimeException sslSupportDisabledException() {
102+
return new IllegalStateException(
103+
"Native SSL support is disabled: you have set quarkus.ssl.native to false in your configuration.");
104+
}
105+
}
106+
}
Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,10 @@
11
package io.quarkus.runtime.graal;
22

3-
import java.io.IOException;
4-
import java.net.InetAddress;
5-
import java.net.Socket;
6-
import java.net.UnknownHostException;
7-
import java.security.KeyManagementException;
83
import java.security.NoSuchAlgorithmException;
94
import java.security.Provider;
10-
import java.security.SecureRandom;
115

12-
import javax.net.ssl.KeyManager;
136
import javax.net.ssl.SSLContext;
147
import javax.net.ssl.SSLContextSpi;
15-
import javax.net.ssl.SSLEngine;
16-
import javax.net.ssl.SSLServerSocketFactory;
17-
import javax.net.ssl.SSLSessionContext;
18-
import javax.net.ssl.SSLSocketFactory;
19-
import javax.net.ssl.TrustManager;
208

219
import com.oracle.svm.core.annotate.Alias;
2210
import com.oracle.svm.core.annotate.Substitute;
@@ -91,92 +79,4 @@ public static synchronized SSLContext getDefault()
9179
// return new Target_javax_net_ssl_SSLContext((SSLContextSpi) instance.impl, instance.provider,
9280
// protocol);
9381
// }
94-
95-
private static class DisabledSSLContext extends SSLContext {
96-
97-
protected DisabledSSLContext() {
98-
super(new DisabledSSLContextSpi(), new Provider("DISABLED", 1, "DISABLED") {
99-
}, "DISABLED");
100-
}
101-
}
102-
103-
private static class DisabledSSLContextSpi extends SSLContextSpi {
104-
105-
@Override
106-
protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers, SecureRandom secureRandom)
107-
throws KeyManagementException {
108-
}
109-
110-
@Override
111-
protected SSLSocketFactory engineGetSocketFactory() {
112-
return new SSLSocketFactory() {
113-
@Override
114-
public String[] getDefaultCipherSuites() {
115-
return new String[0];
116-
}
117-
118-
@Override
119-
public String[] getSupportedCipherSuites() {
120-
return new String[0];
121-
}
122-
123-
@Override
124-
public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
125-
throw sslSupportDisabledException();
126-
}
127-
128-
@Override
129-
public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
130-
throw sslSupportDisabledException();
131-
}
132-
133-
@Override
134-
public Socket createSocket(String s, int i, InetAddress inetAddress, int i1)
135-
throws IOException, UnknownHostException {
136-
throw sslSupportDisabledException();
137-
}
138-
139-
@Override
140-
public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
141-
throw sslSupportDisabledException();
142-
}
143-
144-
@Override
145-
public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1)
146-
throws IOException {
147-
throw sslSupportDisabledException();
148-
}
149-
};
150-
}
151-
152-
@Override
153-
protected SSLServerSocketFactory engineGetServerSocketFactory() {
154-
throw sslSupportDisabledException();
155-
}
156-
157-
@Override
158-
protected SSLEngine engineCreateSSLEngine() {
159-
throw sslSupportDisabledException();
160-
}
161-
162-
@Override
163-
protected SSLEngine engineCreateSSLEngine(String s, int i) {
164-
throw sslSupportDisabledException();
165-
}
166-
167-
@Override
168-
protected SSLSessionContext engineGetServerSessionContext() {
169-
throw sslSupportDisabledException();
170-
}
171-
172-
@Override
173-
protected SSLSessionContext engineGetClientSessionContext() {
174-
throw sslSupportDisabledException();
175-
}
176-
177-
private RuntimeException sslSupportDisabledException() {
178-
return new IllegalStateException(
179-
"Native SSL support is disabled: you have set quarkus.ssl.native to false in your configuration.");
180-
}
181-
}
18282
}

extensions/rest-client/deployment/src/main/java/io/quarkus/restclient/deployment/RestClientProcessor.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
5858
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
5959
import io.quarkus.deployment.builditem.FeatureBuildItem;
60-
import io.quarkus.deployment.builditem.SslNativeConfigBuildItem;
6160
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
6261
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
6362
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
@@ -136,18 +135,15 @@ void setup(BuildProducer<FeatureBuildItem> feature,
136135
}
137136

138137
@BuildStep
139-
@Record(ExecutionTime.STATIC_INIT)
140138
void processInterfaces(CombinedIndexBuildItem combinedIndexBuildItem,
141-
SslNativeConfigBuildItem sslNativeConfig,
142139
Capabilities capabilities,
143140
BuildProducer<NativeImageProxyDefinitionBuildItem> proxyDefinition,
144141
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
145142
BuildProducer<ReflectiveHierarchyBuildItem> reflectiveHierarchy,
146143
BuildProducer<BeanRegistrarBuildItem> beanRegistrars,
147144
BuildProducer<ExtensionSslNativeSupportBuildItem> extensionSslNativeSupport,
148145
BuildProducer<ServiceProviderBuildItem> serviceProvider,
149-
BuildProducer<RestClientBuildItem> restClient,
150-
RestClientRecorder restClientRecorder) {
146+
BuildProducer<RestClientBuildItem> restClient) {
151147

152148
// According to the spec only rest client interfaces annotated with RegisterRestClient are registered as beans
153149
Map<DotName, ClassInfo> interfaces = new HashMap<>();
@@ -220,8 +216,6 @@ public void register(RegistrationContext registrationContext) {
220216

221217
// Indicates that this extension would like the SSL support to be enabled
222218
extensionSslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(FeatureBuildItem.REST_CLIENT));
223-
224-
restClientRecorder.setSslEnabled(sslNativeConfig.isEnabled());
225219
}
226220

227221
private void findInterfaces(IndexView index, Map<DotName, ClassInfo> interfaces, Set<Type> returnTypes,

extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/RestClientBase.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
import org.eclipse.microprofile.config.ConfigProvider;
1717
import org.eclipse.microprofile.context.ManagedExecutor;
1818
import org.eclipse.microprofile.rest.client.RestClientBuilder;
19+
import org.graalvm.nativeimage.ImageInfo;
1920

2021
import io.quarkus.arc.Arc;
2122
import io.quarkus.arc.InstanceHandle;
23+
import io.quarkus.runtime.graal.DisabledSSLContext;
24+
import io.quarkus.runtime.ssl.SslContextConfiguration;
2225

2326
public class RestClientBase {
2427

@@ -77,6 +80,12 @@ private void configureSsl(RestClientBuilder builder) {
7780
if (maybeHostnameVerifier.isPresent()) {
7881
registerHostnameVerifier(maybeHostnameVerifier.get(), builder);
7982
}
83+
84+
// we need to push a disabled SSL context when SSL has been disabled
85+
// because otherwise Apache HTTP Client will try to initialize one and will fail
86+
if (ImageInfo.inImageRuntimeCode() && !SslContextConfiguration.isSslNativeEnabled()) {
87+
builder.sslContext(new DisabledSSLContext());
88+
}
8089
}
8190

8291
private void registerHostnameVerifier(String verifier, RestClientBuilder builder) {

extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/RestClientRecorder.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
public class RestClientRecorder {
2424

2525
public static ResteasyProviderFactory providerFactory;
26-
public static boolean SSL_ENABLED;
2726

2827
public BeanContainerListener hackAroundExtension() {
2928
return new BeanContainerListener() {
@@ -44,11 +43,6 @@ public void setRestClientBuilderResolver() {
4443
RestClientBuilderResolver.setInstance(new BuilderResolver());
4544
}
4645

47-
public void setSslEnabled(boolean sslEnabled) {
48-
SSL_ENABLED = sslEnabled;
49-
RestClientBuilderImpl.setSslEnabled(sslEnabled);
50-
}
51-
5246
public void initializeResteasyProviderFactory(RuntimeValue<InjectorFactory> ifc, boolean useBuiltIn,
5347
Set<String> providersToRegister,
5448
Set<String> contributedProviders) {

extensions/rest-client/runtime/src/main/java/io/quarkus/restclient/runtime/graal/ClientBuilderReplacement.java

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)