Summary of OkHttp source code interpretation (XIII) - > call server interceptor
Tags (space separated): learning notes of OkHttp source code
Preface
- The following summary of relevant knowledge is based on the relevant learning and opinions of mooc.com. If you need to check the relevant teaching of mooc.com, you can still feel it.
Introduction to official website
/** This is the last interceptor in the chain. It makes a network call to the server. */ 1. Initiate a real network request 2. Return the data returned by the server
Main source code
@Override public Response intercept(Chain chain) throws IOException {
//Interceptor chain
RealInterceptorChain realChain = (RealInterceptorChain) chain;
//HttpCodec object source sink two objects input and output / / used to encode request decoding response
HttpCodec httpCodec = realChain.httpStream();
//Other network components used to establish network requests
StreamAllocation streamAllocation = realChain.streamAllocation();
//
RealConnection connection = (RealConnection) realChain.connection();
//Network request
Request request = realChain.request();
long sentRequestMillis = System.currentTimeMillis();
realChain.eventListener().requestHeadersStart(realChain.call());
//Write request header information to socket
httpCodec.writeRequestHeaders(request);
realChain.eventListener().requestHeadersEnd(realChain.call(), request);
Response.Builder responseBuilder = null;
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
// If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100
// Continue" response before transmitting the request body. If we don't get that, return
// what we did get (such as a 4xx response) without ever transmitting the request body.
//Ask if the service can send information with the request body
if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
httpCodec.flushRequest();
realChain.eventListener().responseHeadersStart(realChain.call());
responseBuilder = httpCodec.readResponseHeaders(true);
}
if (responseBuilder == null) {
// Write the request body if the "Expect: 100-continue" expectation was met.
realChain.eventListener().requestBodyStart(realChain.call());
long contentLength = request.body().contentLength();
CountingSink requestBodyOut =
new CountingSink(httpCodec.createRequestBody(request, contentLength));
BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
//Call the request.body().writeTo() method to write the body information to the socket
request.body().writeTo(bufferedRequestBody);
//Close
bufferedRequestBody.close();
realChain.eventListener()
.requestBodyEnd(realChain.call(), requestBodyOut.successfulCount);
} else if (!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.
streamAllocation.noNewStreams();
}
}
//Write operation of network request completed
httpCodec.finishRequest();
if (responseBuilder == null) {
realChain.eventListener().responseHeadersStart(realChain.call());
//Read response through readResponseHeaders of httpCodec
responseBuilder = httpCodec.readResponseHeaders(false);
}
//Create a response object through streamalallocation request
Response response = responseBuilder
.request(request)
.handshake(streamAllocation.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
realChain.eventListener()
.responseHeadersEnd(realChain.call(), response);
//Get response
int code = response.code();
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 {
//Call httpCodec.openResponseBody(response) to create a response
response = response.newBuilder()
.body(httpCodec.openResponseBody(response))
.build();
}
if ("close".equalsIgnoreCase(response.request().header("Connection"))
|| "close".equalsIgnoreCase(response.header("Connection"))) {
//Prevent new streams from creating closed streams and closing connection s
streamAllocation.noNewStreams();
}
//If the code is 204 or 205, an exception will be thrown
if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
throw new ProtocolException(
"HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
}
//Finally, return the response
return response;
}
- 1. Call httpCodec.writeRequestHeaders(request) to write header information to socket object
- 2. request.body().writeTo(bufferedRequestBody) writes body information to socket
- 3. httpCodec.finishRequest() indicates that the writing of network request is completed
- 4. responseBuilder = httpCodec.readResponseHeaders(false) read the header information of the network request
-
5. Read the body information in the network request through the following code logic
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 = response.newBuilder() .body(httpCodec.openResponseBody(response)) .build(); }
General situation of a network request in OkHttp
- 1. Encapsulation of call object to request
- 2. dispatcher distributor distributes requests
- 3. getResponseWithInterceptors() method
- Retryandfollowupinterceptor
- Cacheinterceptor (CACHE)
- Bridgeinterceptor (handles request and response objects against actual request and response Transformations / cookies)
- Connectinterceptor (responsible for establishing intercepting and streaming objects)
- Callserverinterceptor (completes the final network request and read response)