就剩最后一个拦截器CallServerInterceptor了,之前的请看
OKHTTP深入浅出(一)----基础理论_王胖子总叫我减肥的博客-CSDN博客
OKHTTP深入浅出(二)----基本用法_王胖子总叫我减肥的博客-CSDN博客
OKHTTP深入浅出(三)----源码流程_王胖子总叫我减肥的博客-CSDN博客
OKHTTP深入浅出(四)----拦截器(1)RetryAndFollowUpInterceptor_王胖子总叫我减肥的博客-CSDN博客
OKHTTP深入浅出(五)----拦截器(2)ridgeInterceptor与CacheInterceptor_王胖子总叫我减肥的博客-CSDN博客
OKHTTP深入浅出(六)----拦截器(3)ConnectInterceptor_王胖子总叫我减肥的博客-CSDN博客
CallServerInterceptor是拦截器链的最后一个拦截器,它对服务器进行网络调用
public final class CallServerInterceptor implements Interceptor {
private final boolean forWebSocket;
public CallServerInterceptor(boolean forWebSocket) {
this.forWebSocket = forWebSocket;
}
@Override public Response intercept(Chain chain) throws IOException {
RealInterceptorChain realChain = (RealInterceptorChain) chain;
// 这个Exchange是connectionintercept传递过来的。
Exchange exchange = realChain.exchange();
Request request = realChain.request();
long sentRequestMillis = System.currentTimeMillis();
// 将请求头写入到socket中,底层通过Exchangecodec协议类
// 对应http1Exchange 和 http2Exchange,
//最终是通过OKio来实现的,具体实现在realBuffersink类里
exchange.writeRequestHeaders(request);
// 如果请求有body的话,通过okio将body写入到socket中,用于发送给服务器
boolean responseHeadersStarted = false;
Response.Builder responseBuilder = null;
// 含有body的请求
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
// 如果请求头包含EXCEPT:100-continue
// 就会等服务器返回含有http/1.1 100 Continue的响应,然后发送在发送请求body
// 如果没有收到这个响应(例如收到的响应是4XX),那就不发送
if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
exchange.flushRequest();
responseHeadersStarted = true;
exchange.responseHeadersStart();
// 读取响应头
responseBuilder = exchange.readResponseHeaders(true);
}
// responseBuilder为 null,说明服务器返回了100,也就是可以继续发送body了
// 底层通过Exchangecodec协议(http1Exchange 和 http2Exchange)来读取返回header的数据
if (responseBuilder == null) {
if (request.body().isDuplex()) {
// Prepare a duplex body so that the application can send a request body later.
exchange.flushRequest();
BufferedSink bufferedRequestBody = Okio.buffer(
exchange.createRequestBody(request, true));
request.body().writeTo(bufferedRequestBody);
} else {
// 满足了“Expect:100-continue”写请求body
BufferedSink bufferedRequestBody = Okio.buffer(
exchange.createRequestBody(request, false));
request.body().writeTo(bufferedRequestBody);
bufferedRequestBody.close();
}
} else {
//没有满足 "Expect: 100-continue" ,请求发送结束
exchange.noRequestBody();
if (!exchange.connection().isMultiplexed()) {
// If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection
// from being reused. Otherwise we're still obligated to transmit the request body to
// leave the connection in a consistent state.
exchange.noNewExchangesOnConnection();
}
}
} else {
// 没有body请求结束
exchange.noRequestBody();
}
// 请求结束的时候,
if (request.body() == null || !request.body().isDuplex()) {
//真正将写到socket输出流的http请求数据发送。
exchange.finishRequest();
}
// 回调读取响应头的开始事件
if (!responseHeadersStarted) {
exchange.responseHeadersStart();
}
// 读取响应头
if (responseBuilder == null) {
responseBuilder = exchange.readResponseHeaders(false);
}
//创建返回提response
Response response = responseBuilder
.request(request)
.handshake(exchange.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
int code = response.code();
if (code == 100) {
//服务器又返回了一个100,尝试获取真正的响应
response = exchange.readResponseHeaders(false)
.request(request)
.handshake(exchange.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
code = response.code();
}
//回调读取响应头结束
exchange.responseHeadersEnd(response);
// 获取响应body
if (forWebSocket && code == 101) {
// Connection is upgrading, but we need to ensure interceptors see a non-null response body.
response = response.newBuilder()
.body(Util.EMPTY_RESPONSE)
.build();
} else {
//读取response body的数据
// 底层通过Exchangecodec协议(http1Exchange 和 http2Exchange)
response = response.newBuilder()
.body(exchange.openResponseBody(response))
.build();
}
//请求头中的connection是close,表示请求完成后要关闭连接
if ("close".equalsIgnoreCase(response.request().header("Connection"))
|| "close".equalsIgnoreCase(response.header("Connection"))) {
exchange.noNewExchangesOnConnection();
}
// 204 (无内容)205(重置内容)body应该为空
if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
throw new ProtocolException(
"HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
}
return response;
}
}
上述总体就是写入http的请求,读取响应的head和body
无论是读写,都是使用Exchange对应的方法。Exchange理解上是对ExchangeCodec的包装,这写方法内部除了事件回调和一些参数获取外,核心工作都由 ExchangeCodec 对象完成,而 ExchangeCodec实际上利用的是 Okio,而 Okio 实际上还是用的 Socket。
CallServerInterceptor的intercept方法中没有调用连接器链Chain的proceed方法,这是最后一个拦截器。