Skip to content

Commit 7020a49

Browse files
authored
feat: [FFM-12489]: Adding support for HTTP proxies (#205)
* feat: [FFM-12489]: Adding support for HTTP proxies * bump ver * avoid sending password to unknown servers * adding https proxy support * bump ver * fix naming
1 parent dbc1361 commit 7020a49

File tree

6 files changed

+130
-11
lines changed

6 files changed

+130
-11
lines changed

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ dependencyResolutionManagement {
44
versionCatalogs {
55
libs {
66
// main sdk version
7-
version('sdk', '1.8.2');
7+
version('sdk', '1.8.3');
88

99
// sdk deps
1010
version('okhttp3', '4.12.0')
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package io.harness.cf.client.connector;
2+
3+
import javax.net.SocketFactory;
4+
import java.io.IOException;
5+
import java.net.InetAddress;
6+
import java.net.Socket;
7+
8+
final class DelegatingSocketFactory extends SocketFactory {
9+
private final SocketFactory delegate;
10+
11+
public DelegatingSocketFactory(SocketFactory delegate) {
12+
this.delegate = delegate;
13+
}
14+
15+
@Override
16+
public Socket createSocket() throws IOException {
17+
return configureSocket(delegate.createSocket());
18+
}
19+
20+
@Override
21+
public Socket createSocket(String host, int port) throws IOException {
22+
return configureSocket(delegate.createSocket(host, port));
23+
}
24+
25+
@Override
26+
public Socket createSocket(String host, int port, InetAddress localAddress,
27+
int localPort) throws IOException {
28+
return configureSocket(delegate.createSocket(host, port, localAddress, localPort));
29+
}
30+
31+
@Override
32+
public Socket createSocket(InetAddress host, int port) throws IOException {
33+
return configureSocket(delegate.createSocket(host, port));
34+
}
35+
36+
@Override
37+
public Socket createSocket(InetAddress host, int port, InetAddress localAddress,
38+
int localPort) throws IOException {
39+
return configureSocket(delegate.createSocket(host, port, localAddress, localPort));
40+
}
41+
42+
Socket configureSocket(Socket socket) {
43+
return socket;
44+
}
45+
}

src/main/java/io/harness/cf/client/connector/EventSource.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,14 @@ protected OkHttpClient makeStreamClient(long sseReadTimeoutMins, List<X509Certif
7575
throws ConnectorException {
7676
OkHttpClient.Builder httpClientBuilder =
7777
new OkHttpClient.Builder()
78+
.proxy(ProxyConfig.getProxyConfig())
79+
.proxyAuthenticator(ProxyConfig.getProxyAuthentication())
7880
.eventListener(EventListener.NONE)
7981
.readTimeout(sseReadTimeoutMins, TimeUnit.MINUTES)
8082
.retryOnConnectionFailure(true);
8183

84+
ProxyConfig.configureTls(httpClientBuilder);
85+
8286
setupTls(httpClientBuilder, trustedCAs);
8387

8488
if (log.isDebugEnabled()) {

src/main/java/io/harness/cf/client/connector/HarnessConnector.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import lombok.SneakyThrows;
2222
import lombok.extern.slf4j.Slf4j;
2323
import okhttp3.Interceptor;
24+
import okhttp3.OkHttpClient;
2425
import okhttp3.Request;
2526
import okhttp3.Response;
2627
import org.slf4j.MDC;
@@ -87,16 +88,18 @@ ApiClient makeApiClient(int retryBackOfDelay) {
8788

8889
setupTls(apiClient);
8990

91+
final OkHttpClient.Builder builder = apiClient
92+
.getHttpClient()
93+
.newBuilder();
94+
95+
ProxyConfig.configureTls(builder);
96+
9097
// if http client response is 403 we need to reauthenticate
91-
apiClient.setHttpClient(
92-
apiClient
93-
.getHttpClient()
94-
.newBuilder()
95-
.addInterceptor(this::reauthInterceptor)
96-
.addInterceptor(
97-
new NewRetryInterceptor(
98-
options.getMaxRequestRetry(), retryBackOfDelay, isShuttingDown))
99-
.build());
98+
apiClient.setHttpClient(builder.proxy(ProxyConfig.getProxyConfig())
99+
.proxyAuthenticator(ProxyConfig.getProxyAuthentication())
100+
.addInterceptor(this::reauthInterceptor)
101+
.addInterceptor(new NewRetryInterceptor(options.getMaxRequestRetry(), retryBackOfDelay, isShuttingDown))
102+
.build());
100103

101104
return apiClient;
102105
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package io.harness.cf.client.connector;
2+
3+
import java.net.InetSocketAddress;
4+
import java.net.Proxy;
5+
import lombok.extern.slf4j.Slf4j;
6+
import okhttp3.Authenticator;
7+
import okhttp3.Credentials;
8+
import okhttp3.OkHttpClient;
9+
10+
import javax.net.ssl.SSLSocketFactory;
11+
12+
@Slf4j
13+
public class ProxyConfig {
14+
15+
public static Proxy getProxyConfig() {
16+
final String host = System.getProperty("https.proxyHost", System.getProperty("http.proxyHost"));
17+
final String port = System.getProperty("https.proxyPort", System.getProperty("http.proxyPort"));
18+
if (host == null || host.isEmpty() || port == null || port.isEmpty()) {
19+
return Proxy.NO_PROXY;
20+
}
21+
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, Integer.parseInt(port)));
22+
}
23+
24+
public static Authenticator getProxyAuthentication() {
25+
final String user = System.getProperty("http.proxyUser");
26+
final String password = System.getProperty("http.proxyPassword");
27+
if (user == null || user.isEmpty() || password == null || password.isEmpty()) {
28+
return Authenticator.NONE;
29+
}
30+
31+
return (route, response) -> {
32+
final String targetIpPort = getIpAndPort((route == null ? null : route.socketAddress()));
33+
final String configuredIpPort = getIpAndPort((InetSocketAddress) getProxyConfig().address());
34+
35+
if (targetIpPort.equalsIgnoreCase(configuredIpPort)) {
36+
final String credential = Credentials.basic(user, password);
37+
return response.request().newBuilder().header("Proxy-Authorization", credential).build();
38+
} else {
39+
log.warn(
40+
"Target proxy `{}` does not match configured proxy `{}`. Credentials not sent",
41+
targetIpPort,
42+
configuredIpPort);
43+
return null;
44+
}
45+
};
46+
}
47+
48+
private static String getIpAndPort(InetSocketAddress addr) {
49+
if (addr == null) {
50+
return "null";
51+
}
52+
return addr.getAddress().getHostAddress() + ":" + addr.getPort();
53+
}
54+
55+
public static void configureTls(OkHttpClient.Builder builder) {
56+
if (builder == null) {
57+
return;
58+
}
59+
final String host = System.getProperty("https.proxyHost");
60+
final String port = System.getProperty("https.proxyPort");
61+
if (host == null || host.isEmpty() || port == null || port.isEmpty()) {
62+
return;
63+
}
64+
65+
builder.socketFactory(new DelegatingSocketFactory(SSLSocketFactory.getDefault()));
66+
}
67+
}

0 commit comments

Comments
 (0)