44import static io .split .android .client .utils .Utils .checkNotNull ;
55
66import androidx .annotation .NonNull ;
7+ import androidx .annotation .Nullable ;
78
89import java .net .URI ;
910import java .util .concurrent .TimeUnit ;
1718import io .split .android .client .network .CertificatePinningConfiguration ;
1819import io .split .android .client .network .DevelopmentSslConfig ;
1920import io .split .android .client .network .HttpProxy ;
21+ import io .split .android .client .network .ProxyConfiguration ;
2022import io .split .android .client .network .SplitAuthenticator ;
2123import io .split .android .client .service .ServiceConstants ;
2224import io .split .android .client .service .impressions .ImpressionsMode ;
@@ -132,6 +134,8 @@ public class SplitClientConfig {
132134 private final long mImpressionsDedupeTimeInterval ;
133135 @ NonNull
134136 private final RolloutCacheConfiguration mRolloutCacheConfiguration ;
137+ @ Nullable
138+ private final ProxyConfiguration mProxyConfiguration ;
135139
136140 public static Builder builder () {
137141 return new Builder ();
@@ -187,7 +191,8 @@ private SplitClientConfig(String endpoint,
187191 long observerCacheExpirationPeriod ,
188192 CertificatePinningConfiguration certificatePinningConfiguration ,
189193 long impressionsDedupeTimeInterval ,
190- RolloutCacheConfiguration rolloutCacheConfiguration ) {
194+ @ NonNull RolloutCacheConfiguration rolloutCacheConfiguration ,
195+ @ Nullable ProxyConfiguration proxyConfiguration ) {
191196 mEndpoint = endpoint ;
192197 mEventsEndpoint = eventsEndpoint ;
193198 mTelemetryEndpoint = telemetryEndpoint ;
@@ -246,6 +251,7 @@ private SplitClientConfig(String endpoint,
246251 mCertificatePinningConfiguration = certificatePinningConfiguration ;
247252 mImpressionsDedupeTimeInterval = impressionsDedupeTimeInterval ;
248253 mRolloutCacheConfiguration = rolloutCacheConfiguration ;
254+ mProxyConfiguration = proxyConfiguration ;
249255 }
250256
251257 public String trafficType () {
@@ -436,7 +442,9 @@ public boolean persistentAttributesEnabled() {
436442 return mIsPersistentAttributesEnabled ;
437443 }
438444
439- public int offlineRefreshRate () { return mOfflineRefreshRate ; }
445+ public int offlineRefreshRate () {
446+ return mOfflineRefreshRate ;
447+ }
440448
441449 public boolean shouldRecordTelemetry () {
442450 return mShouldRecordTelemetry ;
@@ -446,7 +454,9 @@ public long telemetryRefreshRate() {
446454 return mTelemetryRefreshRate ;
447455 }
448456
449- public boolean syncEnabled () { return mSyncEnabled ; }
457+ public boolean syncEnabled () {
458+ return mSyncEnabled ;
459+ }
450460
451461 public int mtkPerPush () {
452462 return mMtkPerPush ;
@@ -476,7 +486,9 @@ public int sseDisconnectionDelay() {
476486 return mSSEDisconnectionDelayInSecs ;
477487 }
478488
479- private void enableTelemetry () { mShouldRecordTelemetry = true ; }
489+ private void enableTelemetry () {
490+ mShouldRecordTelemetry = true ;
491+ }
480492
481493 public long observerCacheExpirationPeriod () {
482494 return Math .max (mImpressionsDedupeTimeInterval , mObserverCacheExpirationPeriod );
@@ -572,6 +584,8 @@ public static final class Builder {
572584
573585 private RolloutCacheConfiguration mRolloutCacheConfiguration = RolloutCacheConfiguration .builder ().build ();
574586
587+ private ProxyConfiguration mProxyConfiguration = null ;
588+
575589 public Builder () {
576590 mServiceEndpoints = ServiceEndpoints .builder ().build ();
577591 }
@@ -806,7 +820,9 @@ public Builder ready(int milliseconds) {
806820 *
807821 * @param proxyHost proxy URI
808822 * @return this builder
823+ * @deprecated use {@link #proxyConfiguration(ProxyConfiguration)}
809824 */
825+ @ Deprecated
810826 public Builder proxyHost (String proxyHost ) {
811827 if (proxyHost != null && proxyHost .endsWith ("/" )) {
812828 mProxyHost = proxyHost .substring (0 , proxyHost .length () - 1 );
@@ -823,6 +839,7 @@ public Builder proxyHost(String proxyHost) {
823839 * @param proxyAuthenticator
824840 * @return this builder
825841 */
842+ @ Deprecated
826843 public Builder proxyAuthenticator (SplitAuthenticator proxyAuthenticator ) {
827844 mProxyAuthenticator = proxyAuthenticator ;
828845 return this ;
@@ -1030,6 +1047,7 @@ public Builder offlineRefreshRate(int offlineRefreshRate) {
10301047 * <p>
10311048 * This is an ADVANCED parameter
10321049 * </p>
1050+ *
10331051 * @param telemetryRefreshRate Rate in seconds for telemetry refresh.
10341052 * @return This builder
10351053 * @default 3600 seconds
@@ -1101,10 +1119,9 @@ public Builder certificatePinningConfiguration(CertificatePinningConfiguration c
11011119 /**
11021120 * This configuration is used to control the size of the impressions deduplication window.
11031121 *
1122+ * @param impressionsDedupeTimeInterval The time interval in milliseconds.
11041123 * @Experimental This method is experimental and may change or be removed in future versions.
11051124 * To be used upon Split team recommendation.
1106- *
1107- * @param impressionsDedupeTimeInterval The time interval in milliseconds.
11081125 */
11091126 @ Deprecated
11101127 public Builder impressionsDedupeTimeInterval (long impressionsDedupeTimeInterval ) {
@@ -1128,6 +1145,17 @@ public Builder rolloutCacheConfiguration(@NonNull RolloutCacheConfiguration roll
11281145 return this ;
11291146 }
11301147
1148+ /**
1149+ * Sets the proxy configuration
1150+ *
1151+ * @param proxyConfiguration
1152+ * @return this builder
1153+ */
1154+ public Builder proxyConfiguration (ProxyConfiguration proxyConfiguration ) {
1155+ mProxyConfiguration = proxyConfiguration ;
1156+ return this ;
1157+ }
1158+
11311159 public SplitClientConfig build () {
11321160 Logger .instance ().setLevel (mLogLevel );
11331161
@@ -1207,7 +1235,7 @@ public SplitClientConfig build() {
12071235 mImpressionsDedupeTimeInterval = ServiceConstants .DEFAULT_IMPRESSIONS_DEDUPE_TIME_INTERVAL ;
12081236 }
12091237
1210- HttpProxy proxy = parseProxyHost (mProxyHost );
1238+ HttpProxy proxy = parseProxyHost (mProxyHost , mProxyConfiguration );
12111239
12121240 return new SplitClientConfig (
12131241 mServiceEndpoints .getSdkEndpoint (),
@@ -1260,28 +1288,49 @@ public SplitClientConfig build() {
12601288 mObserverCacheExpirationPeriod ,
12611289 mCertificatePinningConfiguration ,
12621290 mImpressionsDedupeTimeInterval ,
1263- mRolloutCacheConfiguration );
1291+ mRolloutCacheConfiguration ,
1292+ mProxyConfiguration );
12641293 }
12651294
1266- private HttpProxy parseProxyHost (String proxyUri ) {
1295+ private HttpProxy parseProxyHost (String proxyUri , ProxyConfiguration proxyConfiguration ) {
1296+ // Use legacy proxy behavior if proxyConfiguration is null
1297+ if (proxyConfiguration == null ) {
1298+ return legacyProxyBehavior (proxyUri );
1299+ }
1300+
1301+ // Initialize internal config with null url. This will be verified when building the factory.
1302+ HttpProxy .Builder builder = HttpProxy .newBuilder (null , -1 );
1303+ if (proxyConfiguration .getUrl () != null ) {
1304+ builder = HttpProxy .newBuilder (proxyConfiguration .getUrl ().getHost (), proxyConfiguration .getUrl ().getPort ())
1305+ .mtlsAuth (proxyConfiguration .getClientCert (), proxyConfiguration .getClientPk ())
1306+ .proxyCacert (proxyConfiguration .getCaCert ())
1307+ .credentialsProvider (proxyConfiguration .getCredentialsProvider ());
1308+ }
1309+ return builder .build ();
1310+ }
1311+
1312+ @ Nullable
1313+ private HttpProxy legacyProxyBehavior (String proxyUri ) {
12671314 if (!Utils .isNullOrEmpty (proxyUri )) {
12681315 try {
12691316 String username = null ;
12701317 String password = null ;
12711318 URI uri = URI .create (proxyUri );
12721319 int port = uri .getPort () != -1 ? uri .getPort () : PROXY_PORT_DEFAULT ;
12731320 String userInfo = uri .getUserInfo ();
1274- if (!Utils .isNullOrEmpty (userInfo )) {
1321+ if (!Utils .isNullOrEmpty (userInfo )) {
12751322 String [] userInfoComponents = userInfo .split (":" );
1276- if (userInfoComponents .length > 1 ) {
1323+ if (userInfoComponents .length > 1 ) {
12771324 username = userInfoComponents [0 ];
12781325 password = userInfoComponents [1 ];
12791326 }
12801327 }
12811328 String host = String .format ("%s%s" , uri .getHost (), uri .getPath ());
1282- return HttpProxy .newBuilder (host , port )
1283- .basicAuth (username , password )
1284- .build ();
1329+ if (username != null && password != null ) {
1330+ return HttpProxy .newBuilder (host , port ).basicAuth (username , password ).build ();
1331+ } else {
1332+ return HttpProxy .newBuilder (host , port ).build ();
1333+ }
12851334 } catch (IllegalArgumentException e ) {
12861335 Logger .e ("Proxy URI not valid: " + e .getLocalizedMessage ());
12871336 throw new IllegalArgumentException ();
0 commit comments