終于到了OKHttp最終發(fā)起請(qǐng)求的地方,在上個(gè)攔截器中找到了一個(gè)連接,客戶端與服務(wù)端已經(jīng)建立起了連接,連接之后我們自然是要從服務(wù)器獲取到我們想要的數(shù)據(jù)了,這時(shí)候就是客戶端與服務(wù)端進(jìn)行數(shù)據(jù)交換操作了;首先呢,在這個(gè)攔截器中拿到上一個(gè)連接攔截器中獲取到的 HttpCodec 和 RealConnection,然后將客戶端的請(qǐng)求頭信息寫入到服務(wù)端:
// 寫入請(qǐng)求頭信息
httpCodec.writeRequestHeaders(request);
realChain.eventListener().requestHeadersEnd(realChain.call(), request);
緊接著會(huì)判斷一下是否有請(qǐng)求體,有的話同樣也會(huì)將請(qǐng)求體也寫入服務(wù)器:
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
httpCodec.flushRequest();
realChain.eventListener().responseHeadersStart(realChain.call());
// 讀取服務(wù)器頭部信息
responseBuilder = httpCodec.readResponseHeaders(true);
}
}
這個(gè)地方有一個(gè)特殊的判斷,“100-continue” 協(xié)議的判斷,這個(gè)是什么東西呢?這個(gè)是客戶端來(lái)詢問(wèn)服務(wù)端是否接受較大的數(shù)據(jù)上傳,比如說(shuō)大圖,文件之類的,那么為什么要這么做呢?舉個(gè)很簡(jiǎn)單的例子,如果客戶端想上傳一張很大的圖片,這時(shí)候如果他先問(wèn)服務(wù)端支不支持,那如果不支持的話,那么客戶端就不會(huì)傳了,也沒(méi)有這個(gè)動(dòng)作,但是如果沒(méi)有事先知道服務(wù)端不支持,那么客戶端就直接傳過(guò)來(lái)了,但是服務(wù)端不會(huì)處理,因?yàn)椴恢С郑幚聿涣?,這個(gè)時(shí)候就浪費(fèi)了上傳的資源,所以這一步就避免了浪費(fèi)資源。然后就是寫入請(qǐng)求體的操作了:
if (responseBuilder == null) {
// Write the request body if the "Expect: 100-continue" expectation was met.
// 寫入請(qǐng)求體
realChain.eventListener().requestBodyStart(realChain.call());
long contentLength = request.body().contentLength();
CountingSink requestBodyOut =
new CountingSink(httpCodec.createRequestBody(request, contentLength));
BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
request.body().writeTo(bufferedRequestBody);
bufferedRequestBody.close();
realChain.eventListener().requestBodyEnd(realChain.call(), requestBodyOut.successfulCount);
}
然后一次請(qǐng)求就結(jié)束了,后面就是讀取響應(yīng)頭的信息以及服務(wù)器返回的數(shù)據(jù):
// 結(jié)束請(qǐng)求
httpCodec.finishRequest();
if (responseBuilder == null) {
// 讀取響應(yīng)頭
realChain.eventListener().responseHeadersStart(realChain.call());
responseBuilder = httpCodec.readResponseHeaders(false);
}
// 構(gòu)建Response對(duì)象
Response response = responseBuilder
.request(request)
.handshake(streamAllocation.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
這里所有的數(shù)據(jù)交換操作都在 HttpCodec 中的 Source 和 Sink 中進(jìn)行,然后就會(huì)構(gòu)造一個(gè) Response 進(jìn)行返回,具體是怎么讀取數(shù)據(jù)流的這個(gè)在Okio框架里面實(shí)現(xiàn),這里不進(jìn)行展開(kāi),后面會(huì)專門講。