18
18
import static software .amazon .awssdk .utils .StringUtils .isEmpty ;
19
19
20
20
import java .net .URI ;
21
+ import java .util .Arrays ;
21
22
import java .util .Collections ;
22
23
import java .util .HashSet ;
23
24
import java .util .Set ;
24
- import software . amazon . awssdk . annotations . ReviewBeforeRelease ;
25
+ import java . util . stream . Collectors ;
25
26
import software .amazon .awssdk .annotations .SdkPublicApi ;
27
+ import software .amazon .awssdk .utils .ProxySystemSetting ;
28
+ import software .amazon .awssdk .utils .StringUtils ;
26
29
import software .amazon .awssdk .utils .ToString ;
27
30
import software .amazon .awssdk .utils .Validate ;
28
31
import software .amazon .awssdk .utils .builder .CopyableBuilder ;
31
34
/**
32
35
* Configuration that defines how to communicate via an HTTP proxy.
33
36
*/
34
- @ ReviewBeforeRelease ("Review which options are required and which are optional." )
35
37
@ SdkPublicApi
36
38
public final class ProxyConfiguration implements ToCopyableBuilder <ProxyConfiguration .Builder , ProxyConfiguration > {
37
39
@@ -42,6 +44,10 @@ public final class ProxyConfiguration implements ToCopyableBuilder<ProxyConfigur
42
44
private final String ntlmWorkstation ;
43
45
private final Set <String > nonProxyHosts ;
44
46
private final Boolean preemptiveBasicAuthenticationEnabled ;
47
+ private final Boolean useSystemPropertyValues ;
48
+ private final String host ;
49
+ private final int port ;
50
+ private final String scheme ;
45
51
46
52
/**
47
53
* Initialize this configuration. Private to require use of {@link #builder()}.
@@ -52,18 +58,38 @@ private ProxyConfiguration(DefaultClientProxyConfigurationBuilder builder) {
52
58
this .password = builder .password ;
53
59
this .ntlmDomain = builder .ntlmDomain ;
54
60
this .ntlmWorkstation = builder .ntlmWorkstation ;
55
- this .nonProxyHosts = Collections . unmodifiableSet ( new HashSet <>( builder .nonProxyHosts )) ;
61
+ this .nonProxyHosts = builder .nonProxyHosts ;
56
62
this .preemptiveBasicAuthenticationEnabled = builder .preemptiveBasicAuthenticationEnabled == null ? Boolean .FALSE :
57
63
builder .preemptiveBasicAuthenticationEnabled ;
64
+ this .useSystemPropertyValues = builder .useSystemPropertyValues ;
65
+ this .host = resolveHost ();
66
+ this .port = resolvePort ();
67
+ this .scheme = resolveScheme ();
58
68
}
59
69
60
70
/**
61
- * The endpoint of the proxy server that the SDK should connect through.
71
+ * Returns the proxy host name either from the configured endpoint or
72
+ * from the "http.proxyHost" system property if {@link Builder#useSystemPropertyValues(Boolean)} is set to true.
73
+ */
74
+ public String host () {
75
+ return host ;
76
+ }
77
+
78
+ /**
79
+ * Returns the proxy port either from the configured endpoint or
80
+ * from the "http.proxyPort" system property if {@link Builder#useSystemPropertyValues(Boolean)} is set to true.
62
81
*
63
- * @see Builder#endpoint(URI)
82
+ * If no value is found in neither of the above options, the default value of 0 is returned.
83
+ */
84
+ public int port () {
85
+ return port ;
86
+ }
87
+
88
+ /**
89
+ * Returns the {@link URI#scheme} from the configured endpoint. Otherwise return null.
64
90
*/
65
- public URI endpoint () {
66
- return endpoint ;
91
+ public String scheme () {
92
+ return scheme ;
67
93
}
68
94
69
95
/**
@@ -72,7 +98,7 @@ public URI endpoint() {
72
98
* @see Builder#password(String)
73
99
*/
74
100
public String username () {
75
- return username ;
101
+ return resolveValue ( username , ProxySystemSetting . PROXY_USERNAME ) ;
76
102
}
77
103
78
104
/**
@@ -81,7 +107,7 @@ public String username() {
81
107
* @see Builder#password(String)
82
108
*/
83
109
public String password () {
84
- return password ;
110
+ return resolveValue ( password , ProxySystemSetting . PROXY_PASSWORD ) ;
85
111
}
86
112
87
113
/**
@@ -105,11 +131,16 @@ public String ntlmWorkstation() {
105
131
/**
106
132
* The hosts that the client is allowed to access without going through the proxy.
107
133
*
134
+ * If the value is not set on the object, the value represent by "http.nonProxyHosts" system property is returned.
135
+ * If system property is also not set, an unmodifiable empty set is returned.
136
+ *
108
137
* @see Builder#nonProxyHosts(Set)
109
138
*/
110
- @ ReviewBeforeRelease ("Revisit the presentation of this option and support http.nonProxyHosts property" )
111
139
public Set <String > nonProxyHosts () {
112
- return nonProxyHosts ;
140
+ Set <String > hosts = nonProxyHosts == null && useSystemPropertyValues ? parseNonProxyHostsProperty ()
141
+ : nonProxyHosts ;
142
+
143
+ return Collections .unmodifiableSet (hosts != null ? hosts : Collections .emptySet ());
113
144
}
114
145
115
146
/**
@@ -152,6 +183,54 @@ public String toString() {
152
183
.build ();
153
184
}
154
185
186
+
187
+ private String resolveHost () {
188
+ return endpoint != null ? endpoint .getHost ()
189
+ : resolveValue (null , ProxySystemSetting .PROXY_HOST );
190
+ }
191
+
192
+ private int resolvePort () {
193
+ int port = 0 ;
194
+
195
+ if (endpoint != null ) {
196
+ port = endpoint .getPort ();
197
+ } else if (useSystemPropertyValues ) {
198
+ port = ProxySystemSetting .PROXY_PORT .getStringValue ()
199
+ .map (Integer ::parseInt )
200
+ .orElse (0 );
201
+ }
202
+
203
+ return port ;
204
+ }
205
+
206
+ public String resolveScheme () {
207
+ return endpoint != null ? endpoint .getScheme () : null ;
208
+ }
209
+
210
+ /**
211
+ * Uses the configuration options, system setting property and returns the final value of the given member.
212
+ */
213
+ private String resolveValue (String value , ProxySystemSetting systemSetting ) {
214
+ return value == null && useSystemPropertyValues ? systemSetting .getStringValue ().orElse (null )
215
+ : value ;
216
+ }
217
+
218
+ /**
219
+ * Returns the Java system property for nonProxyHosts as set of Strings.
220
+ * See http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html.
221
+ */
222
+ private Set <String > parseNonProxyHostsProperty () {
223
+ String nonProxyHosts = ProxySystemSetting .NON_PROXY_HOSTS .getStringValue ().orElse (null );
224
+
225
+ if (!StringUtils .isEmpty (nonProxyHosts )) {
226
+ return Arrays .stream (nonProxyHosts .split ("\\ |" ))
227
+ .map (String ::toLowerCase )
228
+ .map (s -> s .replace ("*" , ".*?" ))
229
+ .collect (Collectors .toSet ());
230
+ }
231
+ return Collections .emptySet ();
232
+ }
233
+
155
234
/**
156
235
* A builder for {@link ProxyConfiguration}.
157
236
*
@@ -202,6 +281,15 @@ public interface Builder extends CopyableBuilder<Builder, ProxyConfiguration> {
202
281
*/
203
282
Builder preemptiveBasicAuthenticationEnabled (Boolean preemptiveBasicAuthenticationEnabled );
204
283
284
+ /**
285
+ * Option whether to use system property values from {@link ProxySystemSetting} if any of the config options are missing.
286
+ *
287
+ * This value is set to "true" by default which means SDK will automatically use system property values
288
+ * for options that are not provided during building the {@link ProxyConfiguration} object. To disable this behavior,
289
+ * set this value to "false".
290
+ */
291
+ Builder useSystemPropertyValues (Boolean useSystemPropertyValues );
292
+
205
293
}
206
294
207
295
/**
@@ -214,8 +302,9 @@ private static final class DefaultClientProxyConfigurationBuilder implements Bui
214
302
private String password ;
215
303
private String ntlmDomain ;
216
304
private String ntlmWorkstation ;
217
- private Set <String > nonProxyHosts = new HashSet <>() ;
305
+ private Set <String > nonProxyHosts ;
218
306
private Boolean preemptiveBasicAuthenticationEnabled ;
307
+ private Boolean useSystemPropertyValues = Boolean .TRUE ;
219
308
220
309
@ Override
221
310
public Builder endpoint (URI endpoint ) {
@@ -282,6 +371,9 @@ public Builder nonProxyHosts(Set<String> nonProxyHosts) {
282
371
283
372
@ Override
284
373
public Builder addNonProxyHost (String nonProxyHost ) {
374
+ if (this .nonProxyHosts == null ) {
375
+ this .nonProxyHosts = new HashSet <>();
376
+ }
285
377
this .nonProxyHosts .add (nonProxyHost );
286
378
return this ;
287
379
}
@@ -300,6 +392,16 @@ public void setPreemptiveBasicAuthenticationEnabled(Boolean preemptiveBasicAuthe
300
392
preemptiveBasicAuthenticationEnabled (preemptiveBasicAuthenticationEnabled );
301
393
}
302
394
395
+ @ Override
396
+ public Builder useSystemPropertyValues (Boolean useSystemPropertyValues ) {
397
+ this .useSystemPropertyValues = useSystemPropertyValues ;
398
+ return this ;
399
+ }
400
+
401
+ public void setUseSystemPropertyValues (Boolean useSystemPropertyValues ) {
402
+ useSystemPropertyValues (useSystemPropertyValues );
403
+ }
404
+
303
405
@ Override
304
406
public ProxyConfiguration build () {
305
407
return new ProxyConfiguration (this );
0 commit comments