Android - 剖析OKHttp(4)- 拦截器RetryA

2020-11-06  本文已影响0人  杨0612

源码分析基于 3.14.4

RetryAndFollowUpInterceptor作用

从名字就能看出,他是负责失败重试以及重定向。

//RetryAndFollowUpInterceptor类中
@Override public Response intercept(Chain chain) throws IOException {
 ......
  while (true) {
    ......
    try {
      response = realChain.proceed(request, transmitter, null);//1
      success = true;
    } catch (RouteException e) {//2
      if (!recover(e.getLastConnectException(), transmitter, false, request)) {
        throw e.getFirstConnectException();
      }
      continue;
    } catch (IOException e) {//3
      boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
      if (!recover(e, transmitter, requestSendStarted, request)) throw e;
      continue;
    } 


    if (priorResponse != null) {
      response = response.newBuilder()
          .priorResponse(priorResponse.newBuilder()
                  .body(null)
                  .build())
          .build();
    }

    Exchange exchange = Internal.instance.exchange(response);
    Route route = exchange != null ? exchange.connection().route() : null;
    Request followUp = followUpRequest(response, route);//4
    ```
    if (followUp == null) {//6
        if (exchange != null && exchange.isDuplex()) {
           transmitter.timeoutEarlyExit();
        }
      return response;
    }

    ......
    RequestBody followUpBody = followUp.body();
    if (followUpBody != null && followUpBody.isOneShot()) {
      return response;
    }
    ......
    if (++followUpCount > MAX_FOLLOW_UPS) {///5
      throw new ProtocolException("Too many follow-up requests: " + followUpCount);
    }

    request = followUp;
    priorResponse = response;
  }
}
//RetryAndFollowUpInterceptor类中
private Request followUpRequest(Response userResponse, @Nullable Route route) throws IOException {
    ......
    switch (responseCode) {
      case HTTP_PROXY_AUTH://1
        ......
        return client.proxyAuthenticator().authenticate(route, userResponse);
      case HTTP_UNAUTHORIZED://2
        return client.authenticator().authenticate(route, userResponse);
      ......
      case HTTP_MOVED_PERM://3
      case HTTP_MOVED_TEMP://4
        if (!client.followRedirects()) return null;
        String location = userResponse.header("Location");
        if (location == null) return null;
        HttpUrl url = userResponse.request().url().resolve(location);
        ......
        return requestBuilder.url(url).build();

      case HTTP_CLIENT_TIMEOUT://5
        ......
        return userResponse.request();
        ......
      default:
        return null;
    }
  }

总结:

以上分析有不对的地方,请指出,互相学习,谢谢哦!

上一篇下一篇

猜你喜欢

热点阅读