/** Returns a strategy to use assuming the request can use the network. */
private CacheStrategy getCandidate() {
// No cached response.
//1、没设置磁盘缓存
if (cacheResponse == null) {
return new CacheStrategy(request, null);
}
// Drop the cached response if it's missing a required handshake.
//2 如果时TLS握手信息丢失,直接进行网络请求
if (request.isHttps() && cacheResponse.handshake() == null) {
return new CacheStrategy(request, null);
}
// 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.
// 3 缓存和请求都设置了no-store(重要信息,禁止缓存)
if (!isCacheable(cacheResponse, request)) {
return new CacheStrategy(request, null);
}
//获取请求的cachecontrol
CacheControl requestCaching = request.cacheControl();
//4、1请求的cacheControl为noCache
//4、2请求头设置了If-Modified-Since或者If-None-Match
if (requestCaching.noCache() || hasConditions(request)) {
return new CacheStrategy(request, null);
}
//走到这里说明缓存可用
//获取缓存的cacheControl
CacheControl responseCaching = cacheResponse.cacheControl();
if (responseCaching.immutable()) {
return new CacheStrategy(null, cacheResponse);
}
//该response已经缓存的时长
long ageMillis = cacheResponseAge();
//该response可以缓存的时长
long freshMillis = computeFreshnessLifetime();
if (requestCaching.maxAgeSeconds() != -1) {
freshMillis = Math.min(freshMillis, SECONDS.toMillis(requestCaching.maxAgeSeconds()));
}
long minFreshMillis = 0;
if (requestCaching.minFreshSeconds() != -1) {
minFreshMillis = SECONDS.toMillis(requestCaching.minFreshSeconds());
}
long maxStaleMillis = 0;
if (!responseCaching.mustRevalidate() && requestCaching.maxStaleSeconds() != -1) {
maxStaleMillis = SECONDS.toMillis(requestCaching.maxStaleSeconds());
}
//5 判断缓存是否过期
if (!responseCaching.noCache() && ageMillis + minFreshMillis < freshMillis + maxStaleMillis) {
Response.Builder builder = cacheResponse.newBuilder();
if (ageMillis + minFreshMillis >= freshMillis) {
builder.addHeader("Warning", "110 HttpURLConnection \"Response is stale\"");
}
long oneDayMillis = 24 * 60 * 60 * 1000L;
if (ageMillis > oneDayMillis && isFreshnessLifetimeHeuristic()) {
builder.addHeader("Warning", "113 HttpURLConnection \"Heuristic expiration\"");
}
// 5.1 缓存没过期直接使用
return new CacheStrategy(null, builder.build());
}
// Find a condition to add to the request. If the condition is satisfied, the response body
// will not be transmitted.
//5.2 缓存已经过期了,判断是否设置了etag和last-Modified标志
String conditionName;
String conditionValue;
if (etag != null) {
conditionName = "If-None-Match";
conditionValue = etag;
} else if (lastModified != null) {
conditionName = "If-Modified-Since";
conditionValue = lastModifiedString;
} else if (servedDate != null) {
conditionName = "If-Modified-Since";
conditionValue = servedDateString;
} else {
return new CacheStrategy(request, null); // No condition! Make a regular request.
}
//设置了etag或者last-modified则添加头部字段,构造请求,交给服务器判断缓存是否可用
Headers.Builder conditionalRequestHeaders = request.headers().newBuilder();
Internal.instance.addLenient(conditionalRequestHeaders, conditionName, conditionValue);
Request conditionalRequest = request.newBuilder()
.headers(conditionalRequestHeaders.build())
.build();
return new CacheStrategy(conditionalRequest, cacheResponse);
}
1、netrequest和cacheresponse 都为空,返回504结束
2、netrequest为空 cacheResponse不空,直接使用强制缓存
3、都不为空表示使用比较缓存,304更新缓存后使用,200缓存失效使用响应
4、netrequest不为空,cacheResponse为空,使用网络并缓存