0
votes

I'm using Retrofit (1.7.1) that uses the default OkHttp (2.1.0) client (I guess) to authenticate on a server and get some session cookies to reply with each other request.

I have a CookieManager and an Interceptor that sets the "Cookie" header.

The interceptor builds the cookie as

 cookieName + "=" + cookieValue + "; "

(I actually use a StringWriter but the results its the same)

The correct headers result should be:

Cookie: PHPSESSID=<my_php_sess_id>; session=<my_session_id>;

BUT

The default implementation (OkHttp I guess) adds another Cookie header resulting in:

Cookie: PHPSESSID=<my_php_sess_id>; session=<my_session_id>;
Cookie: $Version="1"; PHPSESSID="<my_php_sess_id>";$Path="/";$Domain="<my_domain>"; session="<my_session_id>";$Path="/";$Domain="<my_domain>"

I could find the second header only inspecting the network packets with WireShark, all the libraries logs shows only the first one.

I think this second header causes some trouble: note the quotes around the cookie value.

Is there a way to tell OkHttp, or Retrofit, to use the "plain" version of the cookie?
Maybe I misunderstood all the whole Cookie/Client/Interceptor mechanism, but setting the Retrofit client to:

.setClient(new ApacheClient(new DefaultHttpClient()))

solved the problem.

1
Did you find any solution using OkHttp instead of DefaultHttpClient? - Marc Plano-Lesay
I updated the question including Retrofit and OkHttp versions I was using back in December 2014. From that time I haven't tried again. Do you have the same issue with newer versions? - Gnafu
I found a workaround, forcing cookies version to 0. I'll write an answer. - Marc Plano-Lesay

1 Answers

1
votes

I had a similar issue, caused by a webserver which didn't handle version 1 cookies (quoted values). The only way to achieve this that I found is to iterate over your cookie store:

for (HttpCookie cookie: cookieStore.getCookies()) {
    cookie.setVersion(0);
}

But… you need to call this everytime a cookie is changed. I wrote an OkHttp interceptor which does exactly this:

public class CookieBaker implements Interceptor {
    private CookieStore cookieStore;

    public CookieBaker(CookieStore cookieStore) {
        this.cookieStore = cookieStore;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        for (HttpCookie cookie: cookieStore.getCookies()) {
            cookie.setVersion(0);
        }

        Response response = chain.proceed(chain.request());

        for (HttpCookie cookie: cookieStore.getCookies()) {
            cookie.setVersion(0);
        }

        return response;
    }
}

And this is how you enable it:

OkHttpClient httpClient = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
httpClient.setCookieHandler(cookieManager);
httpClient.interceptors().add(new CookieBaker(cookieManager.getCookieStore()));

I do not use Retrofit, but there you should replace your call to .setClient(new ApacheClient(new DefaultHttpClient())) by something like .setClient(httpClient).