Created
May 23, 2013 14:30
-
-
Save dkunzler/5636491 to your computer and use it in GitHub Desktop.
To use square's Picasso image loading library (http://square.github.io/picasso/) with http Basic auth the implementation of a custom loader is necessary. OkHttp (http://square.github.io/okhttp/) is also needed.
Additionally on the server side cache control for such responses has to be enabled explicitly.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// inside Application or Activity, make sure Picasso gets only initalized once | |
Picasso picasso; | |
Builder builder = new Picasso.Builder(this); | |
picasso = builder.loader(new BasicAuthOkHttpLoader(this)).build(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File; | |
import java.io.IOException; | |
import java.net.HttpURLConnection; | |
import java.net.URL; | |
import android.content.Context; | |
import android.os.Environment; | |
import android.util.Log; | |
import com.squareup.okhttp.HttpResponseCache; | |
import com.squareup.okhttp.OkHttpClient; | |
import com.squareup.picasso.Loader; | |
public class BasicAuthOkHttpLoader implements Loader { | |
protected static final String RESPONSE_SOURCE = "X-Android-Response-Source"; | |
private static final String CACHE_DIR_NAME = "images" | |
private static final int MAX_SIZE = 1024 * 1024 * 7; // 7MB (works for us) | |
private OkHttpClient client; | |
public BasicAuthOkHttpLoader(Context context) { | |
client = new OkHttpClient(); | |
try { | |
final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ? context | |
.getExternalCacheDir().getPath() : context.getCacheDir().getPath(); | |
File cacheDir = new File(cachePath + File.separator + CACHE_DIR_NAME); | |
client.setResponseCache(new HttpResponseCache(cacheDir, MAX_SIZE)); | |
} catch (IOException ignored) { | |
} | |
} | |
@Override | |
public Response load(String url, boolean localCacheOnly) throws IOException { | |
HttpURLConnection connection = client.open(new URL(url)); | |
String authString = "username:password"; | |
String authStringEnc = Base64.encodeToString(authString.getBytes(), Base64.NO_WRAP); | |
connection.setRequestProperty("Authorization", "Basic " + authStringEnc); | |
connection.setUseCaches(true); | |
// no caching happens without this setting in our scenario | |
connection.setRequestProperty("Cache-Control", "max-stale=2592000");// 30 days | |
if (localCacheOnly) { | |
connection.setRequestProperty("Cache-Control", "only-if-cached"); | |
} | |
boolean fromCache = parseResponseSourceHeader(connection.getHeaderField(RESPONSE_SOURCE)); | |
return new Response(connection.getInputStream(), fromCache); | |
} | |
/** Returns {@code true} if header indicates the response body was loaded from the disk cache. */ | |
private boolean parseResponseSourceHeader(String header) { | |
if (header == null) { | |
return false; | |
} | |
String[] parts = header.split(" ", 2); | |
if ("CACHE".equals(parts[0])) { | |
return true; | |
} | |
if (parts.length == 1) { | |
return false; | |
} | |
try { | |
return "CONDITIONAL_CACHE".equals(parts[0]) && Integer.parseInt(parts[1]) == 304; | |
} catch (NumberFormatException e) { | |
return false; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// server has to enable cache explicitly for responses that are served with authentication | |
Cache-Control:public |
Hi,
I already replied to you in the square community. This gist is rather outdated, at least the part for the custom Loader.
Something like this should work,without duplicating code from the base class:
https://gist.github.com/stonecs/9068920
For the reference, here the conversation about this:
https://plus.google.com/111643829251040701555/posts/faPTjd8qMzs
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This appears to have gone a little out of date - it looks like there are some extra header fields we need to check now, otherwise disk caching breaks. As per the new source, the header fields are: