Skip to content

Commit 72db195

Browse files
erin889Erin Yang
and
Erin Yang
authored
Use System Property Proxy Settings for Netty and Amazon CRT HTTP Clients (#2771)
* Use system property proxy settings for netty and crt http client Co-authored-by: Erin Yang <[email protected]>
1 parent 195eef8 commit 72db195

File tree

5 files changed

+345
-27
lines changed

5 files changed

+345
-27
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "erin889",
5+
"description": "Use System Property Proxy Settings for Netty and AWS Common Runtime (CRT) HTTP Clients. See [#2321](https://github.com/aws/aws-sdk-java-v2/issues/2321), [#1793](https://github.com/aws/aws-sdk-java-v2/issues/1793)"
6+
}

http-clients/aws-crt-client/src/main/java/software/amazon/awssdk/http/crt/ProxyConfiguration.java

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Objects;
1919
import software.amazon.awssdk.annotations.SdkPreviewApi;
2020
import software.amazon.awssdk.annotations.SdkPublicApi;
21+
import software.amazon.awssdk.utils.ProxySystemSetting;
2122
import software.amazon.awssdk.utils.builder.CopyableBuilder;
2223
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
2324

@@ -39,11 +40,13 @@ public final class ProxyConfiguration implements ToCopyableBuilder<ProxyConfigur
3940

4041
private final String username;
4142
private final String password;
43+
private final Boolean useSystemPropertyValues;
4244

4345
private ProxyConfiguration(BuilderImpl builder) {
46+
this.useSystemPropertyValues = builder.useSystemPropertyValues;
4447
this.scheme = builder.scheme;
45-
this.host = builder.host;
46-
this.port = builder.port;
48+
this.host = resolveHost(builder.host);
49+
this.port = resolvePort(builder.port);
4750
this.username = builder.username;
4851
this.password = builder.password;
4952
}
@@ -56,31 +59,35 @@ public String scheme() {
5659
}
5760

5861
/**
59-
* @return The proxy host.
62+
* @return The proxy host from the configuration if set, or from the "http.proxyHost" system property if
63+
* {@link Builder#useSystemPropertyValues(Boolean)} is set to true
6064
*/
6165
public String host() {
6266
return host;
6367
}
6468

6569
/**
66-
* @return The proxy port.
70+
* @return The proxy port from the configuration if set, or from the "http.proxyPort" system property if
71+
* {@link Builder#useSystemPropertyValues(Boolean)} is set to true
6772
*/
6873
public int port() {
6974
return port;
7075
}
7176

7277
/**
73-
* @return Basic authentication username
74-
*/
78+
* @return The proxy username from the configuration if set, or from the "http.proxyUser" system property if
79+
* {@link Builder#useSystemPropertyValues(Boolean)} is set to true
80+
* */
7581
public String username() {
76-
return username;
82+
return resolveValue(username, ProxySystemSetting.PROXY_USERNAME);
7783
}
7884

7985
/**
80-
* @return Basic authentication password
81-
*/
86+
* @return The proxy password from the configuration if set, or from the "http.proxyPassword" system property if
87+
* {@link Builder#useSystemPropertyValues(Boolean)} is set to true
88+
* */
8289
public String password() {
83-
return password;
90+
return resolveValue(password, ProxySystemSetting.PROXY_PASSWORD);
8491
}
8592

8693
@Override
@@ -182,19 +189,49 @@ public interface Builder extends CopyableBuilder<Builder, ProxyConfiguration> {
182189
* @return This object for method chaining.
183190
*/
184191
Builder password(String password);
192+
193+
/**
194+
* The option whether to use system property values from {@link ProxySystemSetting} if any of the config options
195+
* are missing. The value is set to "true" by default which means SDK will automatically use system property values if
196+
* options are not provided during building the {@link ProxyConfiguration} object. To disable this behaviour, set this
197+
* value to false.
198+
*
199+
* @param useSystemPropertyValues The option whether to use system property values
200+
* @return This object for method chaining.
201+
*/
202+
Builder useSystemPropertyValues(Boolean useSystemPropertyValues);
203+
}
204+
205+
private String resolveHost(String host) {
206+
return resolveValue(host, ProxySystemSetting.PROXY_HOST);
207+
}
208+
209+
private int resolvePort(int port) {
210+
return port == 0 && Boolean.TRUE.equals(useSystemPropertyValues) ?
211+
ProxySystemSetting.PROXY_PORT.getStringValue().map(Integer::parseInt).orElse(0) : port;
212+
}
213+
214+
/**
215+
* Uses the configuration options, system setting property and returns the final value of the given member.
216+
*/
217+
private String resolveValue(String value, ProxySystemSetting systemSetting) {
218+
return value == null && Boolean.TRUE.equals(useSystemPropertyValues) ?
219+
systemSetting.getStringValue().orElse(null) : value;
185220
}
186221

187222
private static final class BuilderImpl implements Builder {
188223
private String scheme;
189224
private String host;
190-
private int port;
225+
private int port = 0;
191226
private String username;
192227
private String password;
228+
private Boolean useSystemPropertyValues = Boolean.TRUE;
193229

194230
private BuilderImpl() {
195231
}
196232

197233
private BuilderImpl(ProxyConfiguration proxyConfiguration) {
234+
this.useSystemPropertyValues = proxyConfiguration.useSystemPropertyValues;
198235
this.scheme = proxyConfiguration.scheme;
199236
this.host = proxyConfiguration.host;
200237
this.port = proxyConfiguration.port;
@@ -232,6 +269,16 @@ public Builder password(String password) {
232269
return this;
233270
}
234271

272+
@Override
273+
public Builder useSystemPropertyValues(Boolean useSystemPropertyValues) {
274+
this.useSystemPropertyValues = useSystemPropertyValues;
275+
return this;
276+
}
277+
278+
public void setUseSystemPropertyValues(Boolean useSystemPropertyValues) {
279+
useSystemPropertyValues(useSystemPropertyValues);
280+
}
281+
235282
@Override
236283
public ProxyConfiguration build() {
237284
return new ProxyConfiguration(this);

http-clients/aws-crt-client/src/test/java/software/amazon/awssdk/http/crt/ProxyConfigurationTest.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,93 @@
2020
import java.lang.reflect.Method;
2121
import java.util.Random;
2222
import java.util.stream.Stream;
23+
import org.junit.AfterClass;
24+
import org.junit.Before;
2325
import org.junit.Test;
2426

2527
/**
2628
* Tests for {@link ProxyConfiguration}.
2729
*/
2830
public class ProxyConfigurationTest {
2931
private static final Random RNG = new Random();
32+
private static final String TEST_HOST = "foo.com";
33+
private static final int TEST_PORT = 7777;
34+
private static final String TEST_USER = "testuser";
35+
private static final String TEST_PASSWORD = "123";
36+
37+
@Before
38+
public void setup() {
39+
clearProxyProperties();
40+
}
41+
42+
@AfterClass
43+
public static void cleanup() {
44+
clearProxyProperties();
45+
}
3046

3147
@Test
3248
public void build_setsAllProperties() {
3349
verifyAllPropertiesSet(allPropertiesSetConfig());
3450
}
3551

52+
@Test
53+
public void build_systemPropertyDefault() {
54+
setProxyProperties();
55+
ProxyConfiguration config = ProxyConfiguration.builder().build();
56+
57+
assertThat(config.host()).isEqualTo(TEST_HOST);
58+
assertThat(config.port()).isEqualTo(TEST_PORT);
59+
assertThat(config.username()).isEqualTo(TEST_USER);
60+
assertThat(config.password()).isEqualTo(TEST_PASSWORD);
61+
assertThat(config.scheme()).isNull();
62+
}
63+
64+
@Test
65+
public void build_systemPropertyEnabled() {
66+
setProxyProperties();
67+
ProxyConfiguration config = ProxyConfiguration.builder().useSystemPropertyValues(Boolean.TRUE).build();
68+
69+
assertThat(config.host()).isEqualTo(TEST_HOST);
70+
assertThat(config.port()).isEqualTo(TEST_PORT);
71+
assertThat(config.username()).isEqualTo(TEST_USER);
72+
assertThat(config.password()).isEqualTo(TEST_PASSWORD);
73+
assertThat(config.scheme()).isNull();
74+
}
75+
76+
@Test
77+
public void build_systemPropertyDisabled() {
78+
setProxyProperties();
79+
ProxyConfiguration config = ProxyConfiguration.builder()
80+
.host("localhost")
81+
.port(8888)
82+
.username("username")
83+
.password("password")
84+
.useSystemPropertyValues(Boolean.FALSE).build();
85+
86+
assertThat(config.host()).isEqualTo("localhost");
87+
assertThat(config.port()).isEqualTo(8888);
88+
assertThat(config.username()).isEqualTo("username");
89+
assertThat(config.password()).isEqualTo("password");
90+
assertThat(config.scheme()).isNull();
91+
}
92+
93+
@Test
94+
public void build_systemPropertyOverride() {
95+
setProxyProperties();
96+
ProxyConfiguration config = ProxyConfiguration.builder()
97+
.host("localhost")
98+
.port(8888)
99+
.username("username")
100+
.password("password")
101+
.build();
102+
103+
assertThat(config.host()).isEqualTo("localhost");
104+
assertThat(config.port()).isEqualTo(8888);
105+
assertThat(config.username()).isEqualTo("username");
106+
assertThat(config.password()).isEqualTo("password");
107+
assertThat(config.scheme()).isNull();
108+
}
109+
36110
@Test
37111
public void toBuilder_roundTrip_producesExactCopy() {
38112
ProxyConfiguration original = allPropertiesSetConfig();
@@ -76,6 +150,8 @@ private void setRandomValue(Object o, Method setter) throws InvocationTargetExce
76150
setter.invoke(o, randomString());
77151
} else if (int.class.equals(paramClass)) {
78152
setter.invoke(o, RNG.nextInt());
153+
} else if (Boolean.class.equals(paramClass)) {
154+
setter.invoke(o, RNG.nextBoolean());
79155
} else {
80156
throw new RuntimeException("Don't know how create random value for type " + paramClass);
81157
}
@@ -108,4 +184,18 @@ private String randomString() {
108184

109185
return sb.toString();
110186
}
187+
188+
private void setProxyProperties() {
189+
System.setProperty("http.proxyHost", TEST_HOST);
190+
System.setProperty("http.proxyPort", Integer.toString(TEST_PORT));
191+
System.setProperty("http.proxyUser", TEST_USER);
192+
System.setProperty("http.proxyPassword", TEST_PASSWORD);
193+
}
194+
195+
private static void clearProxyProperties() {
196+
System.clearProperty("http.proxyHost");
197+
System.clearProperty("http.proxyPort");
198+
System.clearProperty("http.proxyUser");
199+
System.clearProperty("http.proxyPassword");
200+
}
111201
}

0 commit comments

Comments
 (0)