package de.danoeh.antennapod.core.glide;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.bumptech.glide.integration.okhttp.OkHttpStreamFetcher;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Response;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
import de.danoeh.antennapod.core.service.download.HttpDownloader;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* @see com.bumptech.glide.integration.okhttp.OkHttpUrlLoader
*/
public class ApOkHttpUrlLoader implements ModelLoader<GlideUrl, InputStream> {
private static final String TAG = ApOkHttpUrlLoader.class.getSimpleName();
/**
* The default factory for {@link ApOkHttpUrlLoader}s.
*/
public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
private static volatile OkHttpClient internalClient;
private OkHttpClient client;
private static OkHttpClient getInternalClient() {
if (internalClient == null) {
synchronized (Factory.class) {
if (internalClient == null) {
internalClient = AntennapodHttpClient.newHttpClient();
internalClient.interceptors().add(new NetworkAllowanceInterceptor());
internalClient.interceptors().add(new BasicAuthenticationInterceptor());
}
}
}
return internalClient;
}
/**
* Constructor for a new Factory that runs requests using a static singleton client.
*/
public Factory() {
this(getInternalClient());
}
/**
* Constructor for a new Factory that runs requests using given client.
*/
public Factory(OkHttpClient client) {
this.client = client;
}
@Override
public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {
return new ApOkHttpUrlLoader(client);
}
@Override
public void teardown() {
// Do nothing, this instance doesn't own the client.
}
}
private final OkHttpClient client;
public ApOkHttpUrlLoader(OkHttpClient client) {
this.client = client;
}
@Override
public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {
return new OkHttpStreamFetcher(client, model);
}
private static class NetworkAllowanceInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
if (NetworkUtils.isDownloadAllowed()) {
return chain.proceed(chain.request());
} else {
return null;
}
}
}
private static class BasicAuthenticationInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
com.squareup.okhttp.Request request = chain.request();
String url = request.urlString();
String authentication = DBReader.getImageAuthentication(url);
if(TextUtils.isEmpty(authentication)) {
Log.d(TAG, "no credentials for '" + url + "'");
return chain.proceed(request);
}
// add authentication
String[] auth = authentication.split(":");
String credentials = HttpDownloader.encodeCredentials(auth[0], auth[1], "ISO-8859-1");
com.squareup.okhttp.Request newRequest = request
.newBuilder()
.addHeader("Authorization", credentials)
.build();
Log.d(TAG, "Basic authentication with ISO-8859-1 encoding");
Response response = chain.proceed(newRequest);
if (!response.isSuccessful() && response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
credentials = HttpDownloader.encodeCredentials(auth[0], auth[1], "UTF-8");
newRequest = request
.newBuilder()
.addHeader("Authorization", credentials)
.build();
Log.d(TAG, "Basic authentication with UTF-8 encoding");
return chain.proceed(newRequest);
} else {
return response;
}
}
}
}