2
2
3
3
import com .google .common .io .Files ;
4
4
import com .google .gson .Gson ;
5
+ import okhttp3 .Authenticator ;
5
6
import okhttp3 .Cache ;
6
7
import okhttp3 .ConnectionPool ;
8
+ import okhttp3 .Credentials ;
7
9
import okhttp3 .OkHttpClient ;
8
10
import okhttp3 .Request ;
11
+ import okhttp3 .Response ;
12
+ import okhttp3 .Route ;
9
13
import org .slf4j .Logger ;
10
14
import org .slf4j .LoggerFactory ;
11
15
12
16
import java .io .File ;
17
+ import java .io .IOException ;
13
18
import java .net .InetSocketAddress ;
14
19
import java .net .Proxy ;
15
20
import java .net .URI ;
@@ -46,6 +51,7 @@ public final class LDConfig {
46
51
final int socketTimeoutMillis ;
47
52
final int flushInterval ;
48
53
final Proxy proxy ;
54
+ final Authenticator proxyAuthenticator ;
49
55
final OkHttpClient httpClient ;
50
56
final boolean stream ;
51
57
final FeatureStore featureStore ;
@@ -64,6 +70,7 @@ protected LDConfig(Builder builder) {
64
70
this .socketTimeoutMillis = builder .socketTimeoutMillis ;
65
71
this .flushInterval = builder .flushIntervalSeconds ;
66
72
this .proxy = builder .proxy ();
73
+ this .proxyAuthenticator = builder .proxyAuthenticator ();
67
74
this .streamURI = builder .streamURI ;
68
75
this .stream = builder .stream ;
69
76
this .featureStore = builder .featureStore ;
@@ -91,12 +98,24 @@ protected LDConfig(Builder builder) {
91
98
92
99
if (proxy != null ) {
93
100
httpClientBuilder .proxy (proxy );
101
+ if (proxyAuthenticator != null ) {
102
+ httpClientBuilder .proxyAuthenticator (proxyAuthenticator );
103
+ logger .info ("Using proxy: " + proxy + " with authentication." );
104
+ } else {
105
+ logger .info ("Using proxy: " + proxy + " without authentication." );
106
+ }
94
107
}
95
108
96
109
httpClient = httpClientBuilder
97
110
.build ();
98
111
}
99
112
113
+ Request .Builder getRequestBuilder (String sdkKey ) {
114
+ return new Request .Builder ()
115
+ .addHeader ("Authorization" , sdkKey )
116
+ .addHeader ("User-Agent" , "JavaClient/" + LDClient .CLIENT_VERSION );
117
+ }
118
+
100
119
/**
101
120
* A <a href="http://en.wikipedia.org/wiki/Builder_pattern">builder</a> that helps construct {@link com.launchdarkly.client.LDConfig} objects. Builder
102
121
* calls can be chained, enabling the following pattern:
@@ -118,6 +137,8 @@ public static class Builder {
118
137
private int flushIntervalSeconds = DEFAULT_FLUSH_INTERVAL_SECONDS ;
119
138
private String proxyHost = "localhost" ;
120
139
private int proxyPort = -1 ;
140
+ private String proxyUsername = null ;
141
+ private String proxyPassword = null ;
121
142
private boolean stream = true ;
122
143
private boolean useLdd = false ;
123
144
private boolean offline = false ;
@@ -289,6 +310,30 @@ public Builder proxyPort(int port) {
289
310
return this ;
290
311
}
291
312
313
+ /**
314
+ * Sets the username for the optional HTTP proxy. Only used when {@link LDConfig.Builder#proxyPassword(String)}
315
+ * is also called.
316
+ *
317
+ * @param username
318
+ * @return the builder
319
+ */
320
+ public Builder proxyUsername (String username ) {
321
+ this .proxyUsername = username ;
322
+ return this ;
323
+ }
324
+
325
+ /**
326
+ * Sets the password for the optional HTTP proxy. Only used when {@link LDConfig.Builder#proxyUsername(String)}
327
+ * is also called.
328
+ *
329
+ * @param password
330
+ * @return the builder
331
+ */
332
+ public Builder proxyPassword (String password ) {
333
+ this .proxyPassword = password ;
334
+ return this ;
335
+ }
336
+
292
337
/**
293
338
* Deprecated. Only HTTP proxies are currently supported.
294
339
*
@@ -352,7 +397,7 @@ public Builder startWaitMillis(long startWaitMillis) {
352
397
* Enable event sampling. When set to the default of zero, sampling is disabled and all events
353
398
* are sent back to LaunchDarkly. When set to greater than zero, there is a 1 in
354
399
* <code>samplingInterval</code> chance events will be will be sent.
355
- *
400
+ * <p>
356
401
* <p>Example: if you want 5% sampling rate, set <code>samplingInterval</code> to 20.
357
402
*
358
403
* @param samplingInterval the sampling interval.
@@ -386,6 +431,24 @@ Proxy proxy() {
386
431
}
387
432
}
388
433
434
+ Authenticator proxyAuthenticator () {
435
+ if (this .proxyUsername != null && this .proxyPassword != null ) {
436
+ final String credential = Credentials .basic (proxyUsername , proxyPassword );
437
+ return new Authenticator () {
438
+ public Request authenticate (Route route , Response response ) throws IOException {
439
+ if (response .request ().header ("Proxy-Authorization" ) != null ) {
440
+ return null ; // Give up, we've already failed to authenticate with the proxy.
441
+ } else {
442
+ return response .request ().newBuilder ()
443
+ .header ("Proxy-Authorization" , credential )
444
+ .build ();
445
+ }
446
+ }
447
+ };
448
+ }
449
+ return null ;
450
+ }
451
+
389
452
/**
390
453
* Build the configured {@link com.launchdarkly.client.LDConfig} object
391
454
*
@@ -394,12 +457,5 @@ Proxy proxy() {
394
457
public LDConfig build () {
395
458
return new LDConfig (this );
396
459
}
397
-
398
- }
399
-
400
- Request .Builder getRequestBuilder (String sdkKey ) {
401
- return new Request .Builder ()
402
- .addHeader ("Authorization" , sdkKey )
403
- .addHeader ("User-Agent" , "JavaClient/" + LDClient .CLIENT_VERSION );
404
460
}
405
461
}
0 commit comments