overridefunintercept(chain: Interceptor.Chain): Response { val realChain = chain as RealInterceptorChain var request = chain.request val call = realChain.call var followUpCount = 0 var priorResponse: Response? = null var newExchangeFinder = true var recoveredFailures = listOf<IOException>() // 1、重试和重定向的场景依然是在while循环中,不会退出该拦截器 while (true) { // 2、根据需要创建 ExchangeFinder call.enterNetworkInterceptorExchange(request, newExchangeFinder)
var response: Response var closeActiveExchange = true try { if (call.isCanceled()) { throw IOException("Canceled") }
try { // 3、realChain指向下一个拦截器,发生重试或者重定向后, // 会从下一个拦截器开始执行,前面的应用拦截器和此拦截器都不会被执行了 response = realChain.proceed(request) newExchangeFinder = true } catch (e: RouteException) { // The attempt to connect via a route failed. The request will not have been sent. if (!recover(e.lastConnectException, call, request, requestSendStarted = false)) { throw e.firstConnectException.withSuppressed(recoveredFailures) } else { recoveredFailures += e.firstConnectException } newExchangeFinder = false // 4、错误可以恢复,继续while循环 continue } catch (e: IOException) { // An attempt to communicate with a server failed. The request may have been sent. if (!recover(e, call, request, requestSendStarted = e !is ConnectionShutdownException)) { throw e.withSuppressed(recoveredFailures) } else { recoveredFailures += e } newExchangeFinder = false // 5、错误可以恢复,继续while循环 continue }
......
val exchange = call.interceptorScopedExchange // 6、followUpRequest是判断是否重试的主要逻辑,包括重定向、超时重试、用户认证等场景 val followUp = followUpRequest(response, exchange)
if (followUp == null) { if (exchange != null && exchange.isDuplex) { call.timeoutEarlyExit() } closeActiveExchange = false return response }
val followUpBody = followUp.body if (followUpBody != null && followUpBody.isOneShot()) { closeActiveExchange = false return response }
response.body?.closeQuietly()
if (++followUpCount > MAX_FOLLOW_UPS) { throw ProtocolException("Too many follow-up requests: $followUpCount") }