title: HTTP 504 Unsatisfiable Request (only-if-cached)
body: <p>Retrofit2.2.0 and okhttp3.9.1 offline caching not working, When I request offline data will throw an exception that is HTTP 504 Unsatisfiable Request (only-if-cached). Data are loading in the device from the internet, but offline mode cannot retrieval it.</p>
  
  <p>Demonstration:
  <a href="https://i.stack.imgur.com/QtkoQ.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/QtkoQ.jpg" alt="enter image description here"></a></p>
  
  <p>The following code describes the API interface.</p>
  
  <pre><code>public class TestApi {
  
  
      private static TestService testService;
  
      private static final String TEST_URL = "https://httpbin.org/";
  
  
      public static TestService getTestService() {
  
          if(testService == null) {
              synchronized (TestApi.class) {
                  if(testService == null) {
                      testService = XApi.getInstance().getRetrofit(TEST_URL, true).create(TestService.class);
                  }
              }
          }
          return testService;
      }
  
  }
  </code></pre>
  
  <p>The following code describes the API Service.</p>
  
  <pre><code>public interface TestService {
  
      @GET("/cache/60")
      Flowable&lt;TestBean&gt; getTestDate();
  
  }
  </code></pre>
  
  <p>The following code describes the cache control interceptor.</p>
  
  <pre><code>public class CachingControlInterceptor {
  
      private static final int TIMEOUT_CONNECT = 60; //60 second
      private static final int TIMEOUT_DISCONNECT = 60 * 60 * 24 * 7; //7天
  
      public static final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() {
          @Override
          public okhttp3.Response intercept(Chain chain) throws IOException {
              String cache = chain.request().header("cache");
              okhttp3.Response originalResponse = chain.proceed(chain.request());
              String cacheControl = originalResponse.header("Cache-Control");
              if (cacheControl == null) {
                  if (cache == null || "".equals(cache)) {
                      cache = TIMEOUT_CONNECT + "";
                  }
                  originalResponse = originalResponse.newBuilder()
                      .removeHeader("Pragma")
                      .header("Cache-Control", "public, max-age=" + cache)
                      .build();
                  return originalResponse;
              } else {
                  return originalResponse;
              }
          }
      };
  
      public static final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
          @Override
          public okhttp3.Response intercept(Chain chain) throws IOException {
              Request request = chain.request();
              if (!NetworkUtils.isConnected()) {
                  request = request.newBuilder()
                      .removeHeader("Pragma")
                      .header("Cache-Control", "public, only-if-cached, max-stale="+TIMEOUT_DISCONNECT)
                      .build();
              }
              return chain.proceed(request);
          }
      };
  
  }
  </code></pre>
  
  <p>Finally, add an interceptor to OkHttpClient.Builder</p>
  
  <pre><code>Retrofit.Builder builder = new Retrofit.Builder()
      .baseUrl(baseUrl)
      .client(getClient(baseUrl, provider))
      .addConverterFactory(GsonConverterFactory.create());
  
  builder.addNetworkInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR);
  builder.addInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE);
  </code></pre>
  
  <p>And I don't know how to solve it.</p>
  
  <p>Hope anyone could help me!</p>