Picasso can handle basic authentication

This commit is contained in:
Martin Fietz 2015-04-11 23:46:33 +02:00
parent a34acb71d1
commit 9bd6bcf9d3
5 changed files with 98 additions and 5 deletions

View File

@ -13,9 +13,9 @@ dependencies {
compile 'commons-io:commons-io:2.4'
compile 'com.jayway.android.robotium:robotium-solo:5.2.1'
compile 'org.jsoup:jsoup:1.7.3'
compile 'com.squareup.picasso:picasso:2.4.0'
compile 'com.squareup.okhttp:okhttp:2.2.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.okhttp:okhttp:2.3.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.3.0'
compile 'com.squareup.okio:okio:1.2.0'
compile 'de.greenrobot:eventbus:2.4.0'
compile project(':core')

View File

@ -6,8 +6,12 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Response;
import com.squareup.picasso.Cache;
import com.squareup.picasso.LruCache;
import com.squareup.picasso.OkHttpDownloader;
@ -22,13 +26,18 @@ import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import de.danoeh.antennapod.core.service.download.HttpDownloader;
import de.danoeh.antennapod.core.storage.DBReader;
/**
* Provides access to Picasso instances.
*/
public class PicassoProvider {
private static final String TAG = "PicassoProvider";
private static final boolean DEBUG = false;
@ -56,10 +65,12 @@ public class PicassoProvider {
if (picassoSetup) {
return;
}
OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new BasicAuthenticationInterceptor(appContext));
Picasso picasso = new Picasso.Builder(appContext)
.indicatorsEnabled(DEBUG)
.loggingEnabled(DEBUG)
.downloader(new OkHttpDownloader(appContext))
.downloader(new OkHttpDownloader(client))
.addRequestHandler(new MediaRequestHandler(appContext))
.executor(getExecutorService())
.memoryCache(getMemoryCache(appContext))
@ -75,6 +86,45 @@ public class PicassoProvider {
picassoSetup = true;
}
private static class BasicAuthenticationInterceptor implements Interceptor {
private final Context context;
public BasicAuthenticationInterceptor(Context context) {
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
com.squareup.okhttp.Request request = chain.request();
String url = request.urlString();
// add authentication
String authentication = DBReader.getImageAuthentication(context, url);
if(TextUtils.isEmpty(authentication) == false) {
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();
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();
return chain.proceed(newRequest);
} else {
return response;
}
}
else { // no authentication required
return chain.proceed(request);
}
}
}
private static class MediaRequestHandler extends RequestHandler {
final Context context;

View File

@ -272,7 +272,7 @@ public class HttpDownloader extends Downloader {
}
}
private static String encodeCredentials(String username, String password, String charset) {
public static String encodeCredentials(String username, String password, String charset) {
try {
String credentials = username + ":" + password;
byte[] bytes = credentials.getBytes(charset);

View File

@ -711,6 +711,35 @@ public final class DBReader {
return item;
}
/**
* Returns credentials based on image URL
*
* @param context A context that is used for opening a database connection.
* @param imageUrl The URL of the image
* @return Credentials in format "<Username>:<Password>", empty String if no authorization given
*/
public static String getImageAuthentication(final Context context, final String imageUrl) {
Log.d(TAG, "Loading credentials for image with URL " + imageUrl);
PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open();
String credentials = getImageAuthentication(context, imageUrl, adapter);
adapter.close();
return credentials;
}
static String getImageAuthentication(final Context context, final String imageUrl, PodDBAdapter adapter) {
String credentials = null;
Cursor cursor = adapter.getImageAuthenticationCursor(imageUrl);
if (cursor.moveToFirst()) {
String username = cursor.getString(0);
String password = cursor.getString(1);
return username + ":" + password;
}
return "";
}
/**
* Loads a specific FeedItem from the database.
*

View File

@ -1146,6 +1146,20 @@ public class PodDBAdapter {
return db.rawQuery(query, null);
}
public Cursor getImageAuthenticationCursor(final String imageUrl) {
final String query = "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM "
+ TABLE_NAME_FEED_IMAGES + " INNER JOIN " + TABLE_NAME_FEEDS + " ON " +
TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEEDS + "." + KEY_IMAGE + " WHERE "
+ TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "='" + imageUrl + "' UNION SELECT "
+ KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_IMAGES + " INNER JOIN "
+ TABLE_NAME_FEED_ITEMS + " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" +
TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE + " INNER JOIN " + TABLE_NAME_FEEDS + " ON "
+ TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID + " WHERE "
+ TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "='" + imageUrl + "'";
Log.d(TAG, "Query: " + query);
return db.rawQuery(query, null);
}
public int getQueueSize() {
final String query = String.format("SELECT COUNT(%s) FROM %s", KEY_ID, TABLE_NAME_QUEUE);
Cursor c = db.rawQuery(query, null);