Skip to content

Commit 28602e8

Browse files
committed
Support for proxy settings (#228)
1 parent c54ae62 commit 28602e8

File tree

3 files changed

+71
-42
lines changed

3 files changed

+71
-42
lines changed

src/main/com/intellij/lang/jsgraphql/ide/introspection/GraphQLIntrospectionSSLBuilder.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.intellij.lang.jsgraphql.ide.introspection;
22

33
import com.intellij.lang.jsgraphql.ide.project.graphqlconfig.model.GraphQLConfigCertificate;
4+
import com.intellij.lang.jsgraphql.ide.project.graphqlconfig.model.GraphQLConfigSecurity;
5+
import org.apache.http.conn.ssl.TrustAllStrategy;
6+
import org.apache.http.impl.client.HttpClientBuilder;
7+
import org.apache.http.ssl.SSLContextBuilder;
48
import org.jetbrains.annotations.NotNull;
59
import org.jetbrains.annotations.Nullable;
610

@@ -10,6 +14,7 @@
1014
import java.nio.charset.Charset;
1115
import java.nio.file.Files;
1216
import java.nio.file.Path;
17+
import java.nio.file.Paths;
1318
import java.security.*;
1419
import java.security.cert.Certificate;
1520
import java.security.cert.CertificateException;
@@ -19,7 +24,11 @@
1924
import java.util.Base64;
2025
import java.util.Collection;
2126

22-
public class GraphQLIntrospectionSSLBuilder {
27+
public final class GraphQLIntrospectionSSLBuilder {
28+
29+
private GraphQLIntrospectionSSLBuilder() {
30+
}
31+
2332
@NotNull
2433
public static KeyStore makeKeyStore(final Path certPath, final Path keyPath, final GraphQLConfigCertificate.Encoding format)
2534
throws UnsupportedEncodingException {
@@ -91,4 +100,25 @@ private static PrivateKey generatePEMPrivateKey(final Path keyPath) throws IOExc
91100

92101
return privateKey;
93102
}
103+
104+
public static void loadCustomSSLConfiguration(@Nullable GraphQLConfigSecurity sslConfig, @NotNull HttpClientBuilder builder)
105+
throws UnsupportedEncodingException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException,
106+
UnrecoverableKeyException {
107+
if (sslConfig != null && sslConfig.clientCertificate != null && sslConfig.clientCertificateKey != null) {
108+
if (sslConfig.clientCertificate.path == null || sslConfig.clientCertificateKey.path == null) {
109+
throw new RuntimeException("Path needs to be specified for the key and certificate");
110+
}
111+
Path certPath = Paths.get(sslConfig.clientCertificate.path);
112+
Path keyPath = Paths.get(sslConfig.clientCertificateKey.path);
113+
GraphQLConfigCertificate.Encoding keyFormat = sslConfig.clientCertificateKey.format;
114+
115+
KeyStore store = makeKeyStore(certPath, keyPath, keyFormat);
116+
builder.setSSLContext(
117+
new SSLContextBuilder()
118+
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
119+
.loadKeyMaterial(store, null)
120+
.build()
121+
);
122+
}
123+
}
94124
}

src/main/com/intellij/lang/jsgraphql/ide/introspection/GraphQLIntrospectionService.java

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,26 @@
6060
import com.intellij.util.ObjectUtils;
6161
import com.intellij.util.concurrency.annotations.RequiresWriteLock;
6262
import com.intellij.util.messages.MessageBusConnection;
63+
import com.intellij.util.net.IdeHttpClientHelpers;
64+
import com.intellij.util.net.ssl.CertificateManager;
6365
import org.apache.commons.lang.StringEscapeUtils;
66+
import org.apache.http.client.CredentialsProvider;
67+
import org.apache.http.client.config.RequestConfig;
6468
import org.apache.http.client.methods.CloseableHttpResponse;
6569
import org.apache.http.client.methods.HttpPost;
6670
import org.apache.http.client.methods.HttpUriRequest;
71+
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
6772
import org.apache.http.conn.ssl.NoopHostnameVerifier;
68-
import org.apache.http.conn.ssl.TrustAllStrategy;
73+
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
6974
import org.apache.http.entity.ContentType;
7075
import org.apache.http.entity.StringEntity;
71-
import org.apache.http.impl.client.CloseableHttpClient;
72-
import org.apache.http.impl.client.HttpClientBuilder;
73-
import org.apache.http.impl.client.HttpClients;
74-
import org.apache.http.impl.client.LaxRedirectStrategy;
75-
import org.apache.http.ssl.SSLContextBuilder;
76+
import org.apache.http.impl.client.*;
7677
import org.apache.http.util.EntityUtils;
7778
import org.jetbrains.annotations.NotNull;
7879
import org.jetbrains.annotations.Nullable;
7980

81+
import javax.net.ssl.HostnameVerifier;
8082
import java.io.IOException;
81-
import java.nio.file.Path;
82-
import java.nio.file.Paths;
8383
import java.security.*;
8484
import java.security.cert.CertificateException;
8585
import java.util.Collection;
@@ -227,40 +227,39 @@ public GraphQLConfigSecurity getSecurityConfig(@Nullable VirtualFile configFile)
227227
return null;
228228
}
229229

230-
@NotNull
231-
public CloseableHttpClient createHttpClient(@Nullable GraphQLConfigSecurity sslConfig) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, UnrecoverableKeyException, CertificateException {
232-
HttpClientBuilder builder = HttpClients.custom();
233-
builder.setRedirectStrategy(LaxRedirectStrategy.INSTANCE);
234-
235-
if (PropertiesComponent.getInstance(myProject).isTrueValue(GRAPHQL_TRUST_ALL_HOSTS)) {
236-
if (sslConfig != null && sslConfig.clientCertificate != null && sslConfig.clientCertificateKey != null) {
237-
if (sslConfig.clientCertificate.path == null || sslConfig.clientCertificateKey.path == null) {
238-
throw new RuntimeException("Path needs to be specified for the key and certificate");
239-
}
240-
Path certPath = Paths.get(sslConfig.clientCertificate.path);
241-
Path keyPath = Paths.get(sslConfig.clientCertificateKey.path);
242-
GraphQLConfigCertificate.Encoding keyFormat = sslConfig.clientCertificateKey.format;
243-
244-
KeyStore store = GraphQLIntrospectionSSLBuilder.makeKeyStore(certPath, keyPath, keyFormat);
245-
builder
246-
.setSSLContext(
247-
new SSLContextBuilder()
248-
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
249-
.loadKeyMaterial(store, null)
250-
.build())
251-
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
252-
} else {
253-
builder
254-
.setSSLContext(
255-
new SSLContextBuilder()
256-
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
257-
.build())
258-
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
259-
}
260-
}
230+
public @NotNull CloseableHttpClient createHttpClient(@NotNull String url, @Nullable GraphQLConfigSecurity sslConfig)
231+
throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, UnrecoverableKeyException,
232+
CertificateException {
233+
HttpClientBuilder builder = HttpClients.custom()
234+
.setDefaultRequestConfig(createRequestConfig(url))
235+
.setSSLContext(CertificateManager.getInstance().getSslContext())
236+
.setDefaultCredentialsProvider(createCredentialsProvider(url))
237+
.setRedirectStrategy(LaxRedirectStrategy.INSTANCE)
238+
.setSSLHostnameVerifier(createHostnameVerifier());
239+
GraphQLIntrospectionSSLBuilder.loadCustomSSLConfiguration(sslConfig, builder);
240+
return builder.build();
241+
}
242+
243+
private @NotNull RequestConfig createRequestConfig(@NotNull String url) {
244+
RequestConfig.Builder builder = RequestConfig.custom()
245+
.setConnectTimeout(3000)
246+
.setSocketTimeout(5000);
247+
IdeHttpClientHelpers.ApacheHttpClient4.setProxyForUrlIfEnabled(builder, url);
261248
return builder.build();
262249
}
263250

251+
private @NotNull CredentialsProvider createCredentialsProvider(@NotNull String url) {
252+
CredentialsProvider provider = new BasicCredentialsProvider();
253+
IdeHttpClientHelpers.ApacheHttpClient4.setProxyCredentialsForUrlIfEnabled(provider, url);
254+
return provider;
255+
}
256+
257+
private @NotNull HostnameVerifier createHostnameVerifier() {
258+
return PropertiesComponent.getInstance(myProject).isTrueValue(GRAPHQL_TRUST_ALL_HOSTS)
259+
? NoopHostnameVerifier.INSTANCE
260+
: new DefaultHostnameVerifier(PublicSuffixMatcherLoader.getDefault());
261+
}
262+
264263
@Nullable
265264
public NotificationAction createTrustAllHostsAction() {
266265
final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(myProject);
@@ -550,7 +549,7 @@ public void run(@NotNull ProgressIndicator indicator) {
550549
indicator.setIndeterminate(true);
551550
String responseJson;
552551
GraphQLConfigSecurity sslConfig = getSecurityConfig(introspectionSourceFile);
553-
try (final CloseableHttpClient httpClient = createHttpClient(sslConfig);
552+
try (final CloseableHttpClient httpClient = createHttpClient(url, sslConfig);
554553
final CloseableHttpResponse response = httpClient.execute(request)) {
555554
responseJson = ObjectUtils.coalesce(EntityUtils.toString(response.getEntity()), "");
556555
} catch (IOException | GeneralSecurityException e) {

src/main/com/intellij/lang/jsgraphql/ide/project/GraphQLUIProjectService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ private void runQuery(Editor editor, VirtualFile virtualFile, GraphQLQueryContex
364364
try {
365365
VirtualFile configFile = ReadAction.compute(() -> GraphQLConfigManager.getService(myProject).getClosestConfigFile(virtualFile));
366366
GraphQLConfigSecurity sslConfig = introspectionService.getSecurityConfig(configFile);
367-
try (final CloseableHttpClient httpClient = introspectionService.createHttpClient(sslConfig)) {
367+
try (final CloseableHttpClient httpClient = introspectionService.createHttpClient(url, sslConfig)) {
368368
editor.putUserData(GRAPH_QL_EDITOR_QUERYING, true);
369369

370370
String responseJson;

0 commit comments

Comments
 (0)