title: How to refresh Cookies using okhttp3?
body: <p>The REST API I connect to uses <code>cookie-based</code> authorization. Basically, issuing a call, I get a <code>cookie</code>, which then I use in all my requests. That <code>cookie</code> has an expiry time on the Server side. Once <code>cookie</code> expired, I get notified, I have to acquire a new <code>cookie</code> to proceed.
  To achieve this, I am using <code>OkHttp3 client</code>, to which I attached a <code>PersistentCookieJar</code>. Somewhere in between, I also have an <code>Interceptor</code> that catches the <code>session expired</code> responses, and tries to renew the <code>cookie</code>. After my <code>Interceptor</code> does the call to renew the <code>cookie</code>, it <code>re-tries</code> the previously failed call. Which, <strong>fails again</strong>. I suppose it is because the retry of the call is done with <strong>old cookie</strong>.</p>
  
  <p><strong>Any suggestions</strong>?</p>
  
  <p>Some code snippets below:</p>
  
  <pre><code>//OkHttp client with the interceptor and the cookiejar
  OkHttpClient.Builder builder = new OkHttpClient.Builder();
  
  builder.addInterceptor(sessionExpiryInterceptor);
      if (cache != null) {
        builder.cache(cache);
      }
  
  return builder
         .cookieJar(cookieJar)
         .connectTimeout(1, TimeUnit.MINUTES)
         .build();
  </code></pre>
  
  <p>The <code>PersistentCookieJar</code> is used as described here: <a href="https://github.com/franmontiel/PersistentCookieJar" rel="nofollow">https://github.com/franmontiel/PersistentCookieJar</a></p>
  
  <p>And last, the <code>Interceptor:</code></p>
  
  <pre><code>public class SessionExpiryInterceptor implements Interceptor {
  
    @Override public Response intercept(Chain chain) throws IOException {
      final Request request = chain.request();
      final Response response = chain.proceed(request);
      //analyze to see if it is "session expired"
      String bodyString = response.body().string();
      Response copyResponse = copyResponse(response, bodyString);
  
      //attempt to parse the original body
      if (isRefreshRequired(bodyString)) {
        //we send the response copy from here on out, as the original no longer as a "body" - extracted and parsed earlier
        return refreshData(request, copyResponse, chain);
      } else {
        //return the copy since body was extracted earlier
        return copyResponse;
      }
    }
  
      private boolean isRefreshRequired(String responseBody) throws IOException {
      //does some parsing of the responseBody to extract a "status" and "message"
      return status == RESPONSE_CODE_NO_SESSION || message.contains("session");
    }
  
      private Response refreshData(Request request, Response responseCopy, Chain chain) throws IOException {
      //does some checks before attempting to actually refresh the cookie, 
       mAuthService.login(user, pass)
                .subscribeOn(Schedulers.immediate())
                .observeOn(Schedulers.immediate())
                .subscribe(createLoginSubscriber());
      if (mDataRefreshed) {
        // rebuild the request with the new acquired cookie
        Request retry = createRetryRequest(request);
        return chain.proceed(retry);// !!! this call fails again - I get "session expired" response message.
      } else {
        //for whatever reason the refresh failed - send back the original response's copy 
        return responseCopy;
      }
    }
  
      private Subscriber&lt;LoginResponse&gt; createLoginSubscriber() {
      return new Subscriber&lt;LoginResponse&gt;() {
  
        @Override public void onCompleted() {
        }
  
        @Override public void onError(Throwable e) {
          LOG.e(e, "login failed" + e.getMessage());
        }
  
        @Override public void onNext(LoginResponse response) {
          if(response.isSuccess()) {
            mDataRefreshed = true;
          } else {
            mDataRefreshed = false;
            //some cleanup code here
          }
        }
      };
    }
  
      private Request createRetryRequest(Request source) {
      //I suspect this copy might be the issue?
      return source.newBuilder().build();
    }
  
      //copies the given response rewriting the body with the given one with character set UTF-8
    private Response copyResponse(Response original, String body) {
      return original.newBuilder()
              .body(new RealResponseBody(original.headers(), new Buffer().writeUtf8(body)))
              .build();
    }
  }
  </code></pre>