|
/** |
|
from https://github.com/MarkoMilos/android-http/ |
|
**/ |
|
public class PersistentCookieStore implements CookieStore { |
|
|
|
private static final String COOKIE_PREFS = "CookiePrefsFile"; |
|
private static final String COOKIE_NAME_STORE = "names"; |
|
private static final String COOKIE_NAME_PREFIX = "cookie_"; |
|
|
|
private final ConcurrentHashMap<String, Cookie> cookies; |
|
private final SharedPreferences cookiePrefs; |
|
|
|
/** |
|
* Construct a persistent cookie store. |
|
*/ |
|
public PersistentCookieStore(Context context) { |
|
cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, 0); |
|
cookies = new ConcurrentHashMap<String, Cookie>(); |
|
|
|
// Load any previously stored cookies into the store |
|
String storedCookieNames = cookiePrefs.getString(COOKIE_NAME_STORE, null); |
|
if(storedCookieNames != null) { |
|
String[] cookieNames = TextUtils.split(storedCookieNames, ","); |
|
for(String name : cookieNames) { |
|
String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null); |
|
if(encodedCookie != null) { |
|
Cookie decodedCookie = decodeCookie(encodedCookie); |
|
if(decodedCookie != null) { |
|
cookies.put(name, decodedCookie); |
|
} |
|
} |
|
} |
|
|
|
// Clear out expired cookies |
|
clearExpired(new Date()); |
|
} |
|
} |
|
|
|
@Override |
|
public void addCookie(Cookie cookie) { |
|
String name = cookie.getName() + cookie.getDomain(); |
|
|
|
// Save cookie into local store, or remove if expired |
|
if(!cookie.isExpired(new Date())) { |
|
cookies.put(name, cookie); |
|
} else { |
|
cookies.remove(name); |
|
} |
|
|
|
// Save cookie into persistent store |
|
SharedPreferences.Editor prefsWriter = cookiePrefs.edit(); |
|
prefsWriter.putString(COOKIE_NAME_STORE, TextUtils.join(",", cookies.keySet())); |
|
prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableCookie(cookie))); |
|
prefsWriter.commit(); |
|
} |
|
|
|
@Override |
|
public void clear() { |
|
// Clear cookies from persistent store |
|
SharedPreferences.Editor prefsWriter = cookiePrefs.edit(); |
|
for(String name : cookies.keySet()) { |
|
prefsWriter.remove(COOKIE_NAME_PREFIX + name); |
|
} |
|
prefsWriter.remove(COOKIE_NAME_STORE); |
|
prefsWriter.commit(); |
|
|
|
// Clear cookies from local store |
|
cookies.clear(); |
|
} |
|
|
|
@Override |
|
public boolean clearExpired(Date date) { |
|
boolean clearedAny = false; |
|
SharedPreferences.Editor prefsWriter = cookiePrefs.edit(); |
|
|
|
for(ConcurrentHashMap.Entry<String, Cookie> entry : cookies.entrySet()) { |
|
String name = entry.getKey(); |
|
Cookie cookie = entry.getValue(); |
|
if(cookie.isExpired(date)) { |
|
// Clear cookies from local store |
|
cookies.remove(name); |
|
|
|
// Clear cookies from persistent store |
|
prefsWriter.remove(COOKIE_NAME_PREFIX + name); |
|
|
|
// We've cleared at least one |
|
clearedAny = true; |
|
} |
|
} |
|
|
|
// Update names in persistent store |
|
if(clearedAny) { |
|
prefsWriter.putString(COOKIE_NAME_STORE, TextUtils.join(",", cookies.keySet())); |
|
} |
|
prefsWriter.commit(); |
|
|
|
return clearedAny; |
|
} |
|
|
|
@Override |
|
public List<Cookie> getCookies() { |
|
return new ArrayList<Cookie>(cookies.values()); |
|
} |
|
|
|
|
|
// |
|
// Cookie serialization/deserialization |
|
// |
|
|
|
protected String encodeCookie(SerializableCookie cookie) { |
|
ByteArrayOutputStream os = new ByteArrayOutputStream(); |
|
try { |
|
ObjectOutputStream outputStream = new ObjectOutputStream(os); |
|
outputStream.writeObject(cookie); |
|
} catch (Exception e) { |
|
return null; |
|
} |
|
|
|
return byteArrayToHexString(os.toByteArray()); |
|
} |
|
|
|
protected Cookie decodeCookie(String cookieStr) { |
|
byte[] bytes = hexStringToByteArray(cookieStr); |
|
ByteArrayInputStream is = new ByteArrayInputStream(bytes); |
|
Cookie cookie = null; |
|
try { |
|
ObjectInputStream ois = new ObjectInputStream(is); |
|
cookie = ((SerializableCookie)ois.readObject()).getCookie(); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} |
|
|
|
return cookie; |
|
} |
|
|
|
// Using some super basic byte array <-> hex conversions so we don't have |
|
// to rely on any large Base64 libraries. Can be overridden if you like! |
|
protected String byteArrayToHexString(byte[] b) { |
|
StringBuffer sb = new StringBuffer(b.length * 2); |
|
for (byte element : b) { |
|
int v = element & 0xff; |
|
if(v < 16) { |
|
sb.append('0'); |
|
} |
|
sb.append(Integer.toHexString(v)); |
|
} |
|
return sb.toString().toUpperCase(); |
|
} |
|
|
|
protected byte[] hexStringToByteArray(String s) { |
|
int len = s.length(); |
|
byte[] data = new byte[len / 2]; |
|
for(int i=0; i<len; i+=2) { |
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); |
|
} |
|
return data; |
|
} |
|
} |