-
-
Save franmontiel/ed12a2295566b7076161 to your computer and use it in GitHub Desktop.
thank all very much, very useful solution. i use with OkHttp3
Thank you very much it works great.
May I suggest that you will upload this to maven and allow us to use gradle. I hate that I have external code in my project as a raw java file.
Thanks!
@lgalant Proguard obfuscates your SerializableHttpCookie objects.
Add this to your proguard config to avoid this obfuscation problem:
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient ;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
@franmontiel If Proguard is not configured correctly your PersistentCookieStore will fail in a silent and confusing manner:
HttpCookie cookie
will be null here https://gist.github.com/franmontiel/ed12a2295566b7076161#file-persistentcookiestore-java-L47 because an InvalidClassException is being catched in https://gist.github.com/franmontiel/ed12a2295566b7076161#file-serializablehttpcookie-java-L64. Further down the line this will result in a null object being added to the allCookies Map, which in turn will cause a NPE in https://gist.github.com/franmontiel/ed12a2295566b7076161#file-persistentcookiestore-java-L150 as described by @lgalant
Why the stream object in encode/decode methods does not require close?
Why do you use your own checkDomainsMatch(String, String)
and not the function of java.net.HttpCookie
HttpCookie.domainMatches(String, String)
?
@hintsa : thanks man saved me from great deal of headache
the solution you have offered does not respect the expiry of cookies, i have created a nice kotlin version of it which does
https://gist.github.com/leviyehonatan/0c53e89864a0890c2e524d87c6c70c2a
Should i have a single instance of the ClearableCookieJar? or else the PersistentCookieJar is taking care of it ? Sorry if my question sounds stupid.
@manikantagarikipati it might be possible that your are asking about the PersistentCookieJar library?
In any case you should add the CookieStore(this gist) or the CookieJar to the OkHttpClient and you should be using one single OkHttp client.
I've fixed few issues:
- added a workaround for the hasExpire bug (https://code.google.com/p/android/issues/detail?id=191981);
- added support for the session cookies;
- fixed the NPE for the null cookie during deserialization (in the case of missing Proguard rules).
Please feel free to grab the changes from my fork: https://gist.github.com/nuald/ad776c9f7f52d3f6865142bda58c6d3f
If by HttpCookie you mean java.net.HttpCookie then there is a huge mistake in this code.
The java.net.HttpCookie has a private final field called "whenCreated" that is set at consturction time and is used to calculate hasExpired().
Your code is not serializing that value hence after reloading cookies from the persistence all of them get new extended lifetime.
EDIT: I just saw the comment above by nuald and seems someone else has already detected this bug
EDIT2: I was looking for a way to implement persistent cookie store in standard java api not android. The bug that I explained refers to that of the standard java api.
@mrmaffen build fail with yours, i change to below:
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient ;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
FYI, isHttpOnly() and setHttpOnly() methods were added to 24 API version.
I found strange situation in getValidCookies() method.
storedUri may match with uri but allCookies.get(storedUri) return null value.
It leads to crash in:
HttpCookie currentCookie = it.next();
if (currentCookie.hasExpired()) {
I have no Proguard option and I set CookieStore only once..
@agent10
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.net.HttpCookie.hasExpired()' on a null object reference
device:NEXUS 4
client code:
in application onCreate:
CookieManager manager = new CookieManager(
new PersistentCookieStore(this),
CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);
if I comment SerializableHttpCookie.java npe bug will not appear;
line 127 writeObject method out.writeBoolean(getHttpOnly());
line 144 readObject method setHttpOnly(in.readBoolean());
Hi,
While uploading a file using okHttp, facing the following issue. Pls help me to sort it out.
Mentioned the issues:
SerializableHttpCookie: java.lang.NoSuchFieldException: httpOnly
at java.lang.Class.getDeclaredField(Class.java:546)
at in.xxxx.xxxx.SerializableHttpCookie.initFieldHttpOnly(SerializableHttpCookie.java:98)
at in.xxxx.xxxx.SerializableHttpCookie.setHttpOnly(SerializableHttpCookie.java:88)
at in.xxxx.xxxx.SerializableHttpCookie.readObject(SerializableHttpCookie.java:131)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1357)
at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
at in.xxxx.xxxx.SerializableHttpCookie.decode(SerializableHttpCookie.java:62)
at in.xxxx.xxxx.PersistentCookieStore.loadAllFromPersistence(PersistentCookieStore.java:53)
at in.xxxx.xxxx.PersistentCookieStore.(PersistentCookieStore.java:39)
System.err: java.lang.NullPointerException
System.err: at in.xxxx.xxxx.PersistentCookieStore.(PersistentCookieStore.java:37)
System.err: at in.xxxx.xxxx.RequestManager.upload(RequestManager.java:204)
@mrmaffen @torv I also get a build error with these Proguard rules, on the static transient line:
Warning: Exception while processing task java.io.IOException: proguard.ParseException: Expecting java type before ';' in line 32 of file '/Users/julian/AndroidStudioProjects/Twinkle/app/proguard-rules.pro'
It seems like both of you have this line.
Update: I think it's because the real line keeps getting filtered: try quoting it:
!static !transient <fields>;
Been trying to fix the httpOnly problem on API level 18. Thoughts?
08-11 15:36:11.243 3613-3644/me.shreyasr.chatse W/SerializableHttpCookie: java.lang.NullPointerException
at me.shreyasr.chatse.network.cookie.SerializableHttpCookie.getHttpOnly(SerializableHttpCookie.java:100)
at me.shreyasr.chatse.network.cookie.SerializableHttpCookie.writeObject(SerializableHttpCookie.java:142)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1055)
at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1406)
at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1673)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1519)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1483)
at me.shreyasr.chatse.network.cookie.SerializableHttpCookie.encode(SerializableHttpCookie.java:69)
at me.shreyasr.chatse.network.cookie.PersistentCookieStore.saveToPersistence(PersistentCookieStore.java:139)
at me.shreyasr.chatse.network.cookie.PersistentCookieStore.add(PersistentCookieStore.java:132)
at java.net.CookieManager.put(CookieManager.java:188)
at com.squareup.okhttp.internal.http.HttpEngine.receiveHeaders(HttpEngine.java:1054)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:796)
at com.squareup.okhttp.Call.getResponse(Call.java:274)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)
at com.squareup.okhttp.Call.execute(Call.java:81)
at me.shreyasr.chatse.chat.service.IncomingEventService.loadRoom$app_debug(IncomingEventService.kt:65)
at me.shreyasr.chatse.chat.service.IncomingEventServiceBinder.loadRoom(IncomingEventServiceBinder.kt:27)
at me.shreyasr.chatse.chat.ChatActivity$rejoinFavoriteRooms$1.invoke(ChatActivity.kt:481)
at me.shreyasr.chatse.chat.ChatActivity$rejoinFavoriteRooms$1.invoke(ChatActivity.kt:56)
at org.jetbrains.anko.AsyncKt$doAsync$1.invoke(Async.kt:140)
at org.jetbrains.anko.AsyncKt$doAsync$1.invoke(Async.kt)
at org.jetbrains.anko.AsyncKt$sam$Callable$761a5578.call(Async.kt)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
Hi
This Class In Debug Mode Is true
But When Release App Not Work This Class
This Class Has Error :
HttpCookie.hasExpired() is Null Of object Refrence ????
Can anyone tell me how to use this? When I tried to use it, the cookies would not persist application restarts.
thank you very much , it help me so much. awesome code.