aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/http/HttpClient.java
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/http/HttpClient.java152
1 files changed, 136 insertions, 16 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/http/HttpClient.java b/src/main/java/de/thedevstack/conversationsplus/http/HttpClient.java
index 7e12a890..e62be056 100644
--- a/src/main/java/de/thedevstack/conversationsplus/http/HttpClient.java
+++ b/src/main/java/de/thedevstack/conversationsplus/http/HttpClient.java
@@ -1,52 +1,101 @@
package de.thedevstack.conversationsplus.http;
+import android.support.annotation.NonNull;
+
import org.apache.http.conn.ssl.StrictHostnameVerifier;
+import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
+import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.utils.CryptoHelper;
import de.thedevstack.conversationsplus.utils.SSLSocketHelper;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.Interceptor;
+import okhttp3.MediaType;
import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okio.Buffer;
+import okio.BufferedSource;
+import okio.ForwardingSource;
+import okio.Okio;
+import okio.Source;
/**
- * Created by steckbrief on 22.08.2016.
+ *
*/
-public final class HttpClient {
+public final class HttpClient implements Http {
private static HttpClient INSTANCE;
- private boolean interactive = false;
- private OkHttpClient client;
+ private static final String LOGTAG = "http-client";
+
+ private final OkHttpClient client;
- public static void init() {
+ public static synchronized void init() {
INSTANCE = new HttpClient();
}
- public static synchronized OkHttpClient getClient(boolean interactive) {
- if (INSTANCE.interactive != interactive) {
- INSTANCE.interactive = interactive;
- INSTANCE.buildClient();
+ public static synchronized HttpClient getClient() {
+ if (null == INSTANCE) {
+ init();
}
- return INSTANCE.client;
+ return INSTANCE;
}
- private HttpClient() {
- this.buildClient();
+ private static OkHttpClient.Builder getBuilder(boolean interactive) {
+ OkHttpClient.Builder builder = INSTANCE.client.newBuilder();
+ INSTANCE.initTrustManager(builder, interactive);
+
+ return builder;
+ }
+
+ public static synchronized OkHttpClient getOkHttpClient(boolean interactive) {
+ return getBuilder(interactive).build();
+ }
+
+ public static synchronized Call openCancelableAndProgressListenedCall(String url, final ProgressListener progressListener, boolean interactive) {
+ OkHttpClient.Builder builder = getBuilder(interactive);
+ OkHttpClient client = builder.addNetworkInterceptor(new Interceptor() {
+ @Override public Response intercept(Chain chain) throws IOException {
+ Response originalResponse = chain.proceed(chain.request());
+ return originalResponse.newBuilder()
+ .body(new ProgressResponseBody(originalResponse.body(), progressListener))
+ .build();
+ }
+ })
+ .build();
+
+ return client.newCall(new Request.Builder().url(url).build());
}
- private void buildClient() {
+ public static void retrieveHead(String url, @NonNull Callback callback) throws IOException {
+ OkHttpClient client = HttpClient.getOkHttpClient(true);
+ Request request = new Request.Builder()
+ .url(url)
+ //.addHeader(HEADER_NAME_ACCEPT_ENCODING, "")
+ .head()
+ .build();
+ client.newCall(request).enqueue(callback);
+ }
+
+ private HttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
- this.initTrustManager(builder);
+ builder.addInterceptor(new UserAgentInterceptor());
+ builder.addInterceptor(new LoggingInterceptor());
this.client = builder.build();
}
- public void initTrustManager(final OkHttpClient.Builder builder) {
+ private static void initTrustManager(final OkHttpClient.Builder builder, final boolean interactive) {
final X509TrustManager trustManager;
final HostnameVerifier hostnameVerifier;
if (interactive) {
@@ -78,4 +127,75 @@ public final class HttpClient {
} catch (final KeyManagementException | NoSuchAlgorithmException ignored) {
}
}
+
+ private static class UserAgentInterceptor implements Interceptor, Http {
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request originalRequest = chain.request();
+ Request requestWithUserAgent = originalRequest.newBuilder()
+ .header(USER_AGENT_REQUEST_PROPERTY_NAME, ConversationsPlusApplication.getNameAndVersion())
+ .build();
+ return chain.proceed(requestWithUserAgent);
+ }
+ }
+
+ private static class LoggingInterceptor implements Interceptor {
+ @Override public Response intercept(Interceptor.Chain chain) throws IOException {
+ Request request = chain.request();
+
+ long t1 = System.nanoTime();
+ Logging.d(LOGTAG, String.format(Locale.getDefault(), "Sending %s request %s on %s%n%s",
+ request.method(), request.url(), chain.connection(), request.headers()));
+
+ Response response = chain.proceed(request);
+
+ long t2 = System.nanoTime();
+ Logging.d(LOGTAG, String.format(Locale.getDefault(), "Received response for %s request %s in %.1fms%n%s",
+ response.request().method(), response.request().url(), (t2 - t1) / 1e6d, response.headers()));
+
+ return response;
+ }
+ }
+
+ private static class ProgressResponseBody extends ResponseBody {
+
+ private final ResponseBody responseBody;
+ private final ProgressListener progressListener;
+ private BufferedSource bufferedSource;
+
+ public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
+ this.responseBody = responseBody;
+ this.progressListener = progressListener;
+ }
+
+ @Override public MediaType contentType() {
+ return responseBody.contentType();
+ }
+
+ @Override public long contentLength() {
+ return responseBody.contentLength();
+ }
+
+ @Override public BufferedSource source() {
+ if (bufferedSource == null) {
+ bufferedSource = Okio.buffer(source(responseBody.source()));
+ }
+ return bufferedSource;
+ }
+
+ private Source source(Source source) {
+ return new ForwardingSource(source) {
+
+ @Override public long read(Buffer sink, long byteCount) throws IOException {
+ long bytesRead = super.read(sink, byteCount);
+ // read() returns the number of bytes read, or -1 if this source is exhausted.
+ boolean done = bytesRead == -1;
+ long currentBytesRead = !done ? bytesRead : 0;
+ progressListener.update(currentBytesRead, responseBody.contentLength(), done);
+ return bytesRead;
+ }
+ };
+ }
+ }
}