/** Returns the source to satisfy {@code request} given this cached response. */ public ResponseSource chooseResponseSource(long nowMillis, RequestHeaders request) { /* * If this response shouldn't have been stored, it should never be used * as a response source. This check should be redundant as long as the * persistence store is well-behaved and the rules are constant. */ if (!isCacheable(request)) { return ResponseSource.NETWORK; } if (request.isNoCache() || request.hasConditions()) { return ResponseSource.NETWORK; } long ageMillis = computeAge(nowMillis); long freshMillis = computeFreshnessLifetime(); if (request.getMaxAgeSeconds() != -1) { freshMillis = Math.min(freshMillis, TimeUnit.SECONDS.toMillis(request.getMaxAgeSeconds())); } long minFreshMillis = 0; if (request.getMinFreshSeconds() != -1) { minFreshMillis = TimeUnit.SECONDS.toMillis(request.getMinFreshSeconds()); } long maxStaleMillis = 0; if (!mustRevalidate && request.getMaxStaleSeconds() != -1) { maxStaleMillis = TimeUnit.SECONDS.toMillis(request.getMaxStaleSeconds()); } if (!noCache && ageMillis + minFreshMillis < freshMillis + maxStaleMillis) { if (ageMillis + minFreshMillis >= freshMillis) { headers.add("Warning", "110 HttpURLConnection \"Response is stale\""); } /* * not available in API 8 if (ageMillis > TimeUnit.HOURS.toMillis(24) && isFreshnessLifetimeHeuristic()) { */ if (ageMillis > 24L * 60L * 60L * 1000L && isFreshnessLifetimeHeuristic()) { headers.add("Warning", "113 HttpURLConnection \"Heuristic expiration\""); } return ResponseSource.CACHE; } if (etag != null) { request.setIfNoneMatch(etag); } else if (lastModified != null) { request.setIfModifiedSince(lastModified); } else if (servedDate != null) { request.setIfModifiedSince(servedDate); } return request.hasConditions() ? ResponseSource.CONDITIONAL_CACHE : ResponseSource.NETWORK; }