// okhttp3.internal.http.BridgeInterceptor#interceptif(userRequest.header("Connection")==null){
requestBuilder.header("Connection","Keep-Alive");}// If we add an "Accept-Encoding: gzip" header field we're responsible for also decompressing// the transfer stream.boolean transparentGzip =false;if(userRequest.header("Accept-Encoding")==null&& userRequest.header("Range")==null){
transparentGzip =true;
requestBuilder.header("Accept-Encoding","gzip");}
// okhttp3.internal.cache.CacheStrategy.Factory/**
* Returns a strategy to satisfy {@code request} using the a cached response {@code response}.
*/publicCacheStrategyget(){
CacheStrategy candidate =getCandidate();// 根据request请求和缓存中的Response决定后续的网络请求步骤// 禁止同时有networkRequest 和 onlyIfCached配置。if(candidate.networkRequest !=null&& request.cacheControl().onlyIfCached()){
// 注释8// We're forbidden from using the network and the cache is insufficient.returnnewCacheStrategy(null,null);// 此处为空,会报`504`错误。}return candidate;}/** Returns a strategy to use assuming the request can use the network. */privateCacheStrategygetCandidate(){
// No cached response.if(cacheResponse ==null){
// 注释1returnnewCacheStrategy(request,null);}// Drop the cached response if it's missing a required handshake.if(request.isHttps()&& cacheResponse.handshake()==null){
// 注释2returnnewCacheStrategy(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.if(!isCacheable(cacheResponse, request)){
// 注释3returnnewCacheStrategy(request,null);}CacheControl requestCaching = request.cacheControl();// 获取请求中的cacheControl配置if(requestCaching.noCache()||hasConditions(request)){
// 注释4returnnewCacheStrategy(request,null);}CacheControl responseCaching = cacheResponse.cacheControl();// 注释5long ageMillis =cacheResponseAge();// 计算缓存从生成开始,已经度过了多长时间long freshMillis =computeFreshnessLifetime();// 返回Response配置的max-age,最大可存活的生命时间if(requestCaching.maxAgeSeconds()!=-1){
// cacheResponse中配置的max-age 和 request中配置的max-age中,取最小的一个值。// 此处就最终计算出来允许Response有效时间
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());}// 如果缓存没有过期,满足当前request的要求,那么直接使用缓存作为结果。if(!responseCaching.noCache()&& ageMillis + minFreshMillis < freshMillis + maxStaleMillis){
// 注释6Response.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\"");}returnnewCacheStrategy(null, builder.build());}// Find a condition to add to the request. If the condition is satisfied, the response body// will not be transmitted.String conditionName;String conditionValue;if(etag !=null){
// 注释7
conditionName ="If-None-Match";
conditionValue = etag;}elseif(lastModified !=null){
conditionName ="If-Modified-Since";
conditionValue = lastModifiedString;}elseif(servedDate !=null){
conditionName ="If-Modified-Since";
conditionValue = servedDateString;}else{
returnnewCacheStrategy(request,null);// No condition! Make a regular request.}Headers.Builder conditionalRequestHeaders = request.headers().newBuilder();Internal.instance.addLenient(conditionalRequestHeaders, conditionName, conditionValue);// 添加到requestRequest conditionalRequest = request.newBuilder().headers(conditionalRequestHeaders.build()).build();returnnewCacheStrategy(conditionalRequest, cacheResponse);}