Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions http-domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ dependencies {

testImplementation libs.junit4
testImplementation libs.mockitoCore
testImplementation libs.mockitoInline
testImplementation libs.okhttpTls
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.split.android.client.network;

public class Algorithm {

public static final String SHA256 = "sha256";
public static final String SHA1 = "sha1";
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import java.util.Map;

interface AuthenticatedRequest<T> {
public interface AuthenticatedRequest {

void setHeader(@NonNull String name, @NonNull String value);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.split.android.client.network;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public interface Authenticator {

@Nullable AuthenticatedRequest authenticate(@NonNull AuthenticatedRequest request);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.split.android.client.network;

interface Base64Decoder {
public interface Base64Decoder {

byte[] decode(String base64);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

import io.split.android.client.utils.logger.Logger;

class CertificateCheckerHelper {
public class CertificateCheckerHelper {

@Nullable
static Set<CertificatePin> getPinsForHost(String pattern, Map<String, Set<CertificatePin>> configuredPins) {
public static Set<CertificatePin> getPinsForHost(String pattern, Map<String, Set<CertificatePin>> configuredPins) {
Set<CertificatePin> hostPins = configuredPins.get(pattern);
Set<CertificatePin> wildcardPins = new LinkedHashSet<>();

Expand Down Expand Up @@ -53,7 +53,7 @@ static Set<CertificatePin> getPinsForHost(String pattern, Map<String, Set<Certif
}

@NonNull
static Set<CertificatePin> getPinsFromInputStream(InputStream inputStream, PinEncoder pinEncoder) {
public static Set<CertificatePin> getPinsFromInputStream(InputStream inputStream, PinEncoder pinEncoder) {
try (InputStream stream = inputStream) {
CertificateFactory factory = CertificateFactory.getInstance("X.509");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package io.split.android.client.network;

import com.google.gson.annotations.SerializedName;

import java.util.Arrays;
import java.util.Objects;

public class CertificatePin {

@SerializedName("pin")
private final byte[] mPin;
@SerializedName("algo")
private final String mAlgorithm;

CertificatePin(byte[] pin, String algorithm) {
public CertificatePin(byte[] pin, String algorithm) {
mPin = pin;
mAlgorithm = algorithm;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.util.Map;
import java.util.Set;

import io.split.android.client.utils.Base64Util;
import io.split.android.client.utils.logger.Logger;

public class CertificatePinningConfiguration {
Expand Down Expand Up @@ -160,7 +159,7 @@ public Builder failureListener(@NonNull CertificatePinningFailureListener failur
}

// Meant to be used only when setting up bg sync jobs
void addPins(String host, Set<CertificatePin> pins) {
public void addPins(String host, Set<CertificatePin> pins) {
if (host == null || host.trim().isEmpty()) {
Logger.e("Host cannot be null or empty. Ignoring entry");
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.split.android.client.network;

import android.util.Base64;

import io.split.android.client.utils.logger.Logger;

public class DefaultBase64Decoder implements Base64Decoder {

@Override
public byte[] decode(String base64) {
try {
return Base64.decode(base64, Base64.DEFAULT);
} catch (IllegalArgumentException e) {
Logger.e("Received bytes didn't correspond to a valid Base64 encoded string." + e.getLocalizedMessage());
} catch (Exception e) {
Logger.e("An unknown error has occurred " + e.getLocalizedMessage());
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package io.split.android.client.network;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;


public class HttpClientConfiguration {

private final long mConnectionTimeout;
private final long mReadTimeout;
@Nullable
private final HttpProxy mProxy;
@Nullable
private final CertificatePinningConfiguration mCertificatePinningConfiguration;
@Nullable
private final DevelopmentSslConfig mDevelopmentSslConfig;
@Nullable
private final SplitAuthenticator mProxyAuthenticator;

private HttpClientConfiguration(Builder builder) {
mConnectionTimeout = builder.mConnectionTimeout;
mReadTimeout = builder.mReadTimeout;
mProxy = builder.mProxy;
mCertificatePinningConfiguration = builder.mCertificatePinningConfiguration;
mDevelopmentSslConfig = builder.mDevelopmentSslConfig;
mProxyAuthenticator = builder.mProxyAuthenticator;
}

public long getConnectionTimeout() {
return mConnectionTimeout;
}

public long getReadTimeout() {
return mReadTimeout;
}

@Nullable
public HttpProxy getProxy() {
return mProxy;
}

@Nullable
public CertificatePinningConfiguration getCertificatePinningConfiguration() {
return mCertificatePinningConfiguration;
}

@Nullable
public DevelopmentSslConfig getDevelopmentSslConfig() {
return mDevelopmentSslConfig;
}

@Nullable
public SplitAuthenticator getProxyAuthenticator() {
return mProxyAuthenticator;
}

@NonNull
public static Builder builder() {
return new Builder();
}

public static class Builder {

private long mConnectionTimeout;
private long mReadTimeout;
@Nullable
private HttpProxy mProxy;
@Nullable
private CertificatePinningConfiguration mCertificatePinningConfiguration;
@Nullable
private DevelopmentSslConfig mDevelopmentSslConfig;
@Nullable
private SplitAuthenticator mProxyAuthenticator;

private Builder() {
}

/**
* Sets the connection timeout in milliseconds.
*/
@NonNull
public Builder connectionTimeout(long connectionTimeout) {
mConnectionTimeout = connectionTimeout;
return this;
}

/**
* Sets the read timeout in milliseconds.
*/
@NonNull
public Builder readTimeout(long readTimeout) {
mReadTimeout = readTimeout;
return this;
}

/**
* Sets the HTTP proxy configuration.
*/
@NonNull
public Builder proxy(@Nullable HttpProxy proxy) {
mProxy = proxy;
return this;
}

/**
* Sets the certificate pinning configuration.
*/
@NonNull
public Builder certificatePinningConfiguration(@Nullable CertificatePinningConfiguration configuration) {
mCertificatePinningConfiguration = configuration;
return this;
}

/**
* Sets the development SSL configuration.
* <p>
* This is intended for development/testing environments only.
*/
@NonNull
public Builder developmentSslConfig(@Nullable DevelopmentSslConfig developmentSslConfig) {
mDevelopmentSslConfig = developmentSslConfig;
return this;
}

/**
* Sets the proxy authenticator.
*/
@NonNull
public Builder proxyAuthenticator(@Nullable SplitAuthenticator proxyAuthenticator) {
mProxyAuthenticator = proxyAuthenticator;
return this;
}

/**
* Builds the configuration.
*/
@NonNull
public HttpClientConfiguration build() {
return new HttpClientConfiguration(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import androidx.annotation.NonNull;

interface PinEncoder {
public interface PinEncoder {

@NonNull
byte[] encodeCertPin(String algorithm, byte[] encodedPublicKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import io.split.android.client.utils.logger.Logger;

class PinEncoderImpl implements PinEncoder {
public class PinEncoderImpl implements PinEncoder {

@Override
@NonNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.split.android.client.network;

/** @noinspection unused*/
public abstract class SplitAuthenticator implements Authenticator<SplitAuthenticatedRequest> {
public abstract class SplitAuthenticator implements Authenticator {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.split.android.client.network;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import org.junit.Test;

public class HttpClientConfigurationTest {

@Test
public void builderSetsConnectionTimeout() {
HttpClientConfiguration config = HttpClientConfiguration.builder()
.connectionTimeout(15_000)
.build();

assertEquals(15_000, config.getConnectionTimeout());
}

@Test
public void builderSetsReadTimeout() {
HttpClientConfiguration config = HttpClientConfiguration.builder()
.readTimeout(30_000)
.build();

assertEquals(30_000, config.getReadTimeout());
}

@Test
public void builderSetsProxy() {
HttpProxy proxy = HttpProxy.newBuilder("proxy.example.com", 8080).build();
HttpClientConfiguration config = HttpClientConfiguration.builder()
.proxy(proxy)
.build();

assertNotNull(config.getProxy());
assertEquals("proxy.example.com", config.getProxy().getHost());
assertEquals(8080, config.getProxy().getPort());
}

@Test
public void builderSetsCertificatePinningConfiguration() {
CertificatePinningConfiguration certConfig = CertificatePinningConfiguration.builder()
.addPin("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build();
HttpClientConfiguration config = HttpClientConfiguration.builder()
.certificatePinningConfiguration(certConfig)
.build();

assertNotNull(config.getCertificatePinningConfiguration());
}

@Test
public void builderSetsDevelopmentSslConfig() {
// DevelopmentSslConfig requires non-null args; just verify null default
HttpClientConfiguration config = HttpClientConfiguration.builder().build();
assertNull(config.getDevelopmentSslConfig());
}

@Test
public void builderSetsProxyAuthenticator() {
HttpClientConfiguration config = HttpClientConfiguration.builder().build();
assertNull(config.getProxyAuthenticator());
}

@Test
public void defaultValuesAreZeroAndNull() {
HttpClientConfiguration config = HttpClientConfiguration.builder().build();

assertEquals(0, config.getConnectionTimeout());
assertEquals(0, config.getReadTimeout());
assertNull(config.getProxy());
assertNull(config.getCertificatePinningConfiguration());
assertNull(config.getDevelopmentSslConfig());
assertNull(config.getProxyAuthenticator());
}

@Test
public void builderSetsAllFields() {
HttpProxy proxy = HttpProxy.newBuilder("proxy.example.com", 8080).build();
CertificatePinningConfiguration certConfig = CertificatePinningConfiguration.builder()
.addPin("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build();

HttpClientConfiguration config = HttpClientConfiguration.builder()
.connectionTimeout(10_000)
.readTimeout(20_000)
.proxy(proxy)
.certificatePinningConfiguration(certConfig)
.build();

assertEquals(10_000, config.getConnectionTimeout());
assertEquals(20_000, config.getReadTimeout());
assertNotNull(config.getProxy());
assertNotNull(config.getCertificatePinningConfiguration());
}
}
Loading
Loading