• The OkHttp source version used for this article is 3.12.10

The last:OkHttp: CacheInterceptor

An appetizer

  • Before we get to the interceptor, let’s add a bit of network basics. Most people are probably aware that the biggest difference between Http and Https is the use of encrypted transport to make requests more secure, but most people don’t know the difference between different versions of Http.

  • The biggest change between Http 1.0 and Http 1.1 is that Http 1.1 has the long connection feature, so the question is, what is a long connection?

    • We all know that Http is an application layer protocol derived from TCP. We can think of Http as a subclass of TCP. When it comes to TCP, the first thing that comes to mind may be the three-way handshake, in which three network signals are sent before establishing a connection. This pattern is also found in Http, but there are some differences between Http 1.0 and Http 1.1. Http 1.0 requires three handshakes for each request and the connection is automatically disconnected. Http 1.1 optimizes this area. Instead of immediately disconnecting the connection after each request, the connection is reused and the next request to the network is established without a three-way handshake. This is the long connection feature of Http 1.1.

    • The advantage of this is that, because the three-way handshake consumes time and resources, if the network needs three handshakes to establish a connection for each request, under this condition, the server will undoubtedly form a certain pressure burden, and the same client will also be affected to a certain extent. Therefore, reuse of the three-way handshake can greatly reduce the pressure on the server and improve the response speed of the client.

  • The biggest thing about Http 1.1 and Http 2.0 is that Http 2.0 has multiplexing features, so the question is, what is multiplexing?

    • Due to long connection characteristics of Http 1.1 can handle only a single request, and if so request a more will lead to line up, a number of request queue serialization single thread processing, behind the front waiting for request return to seize the opportunity of execution, once a request timeout, subsequent requests can only be blocked, and there is no way, That’s what people call a plug. Http 2.0 allows multiple requests to be executed in parallel on a single connection at the same time. If one request task is too time-consuming, other requests will not be affected.

The source code parsing

  • Your first impression of this interceptor is that it feels so easy with so little code

  • Yeah, that’s what I thought the first time I saw it, but then I changed my mind

  • This is obviously not important code, so I’m going to skip it

  • This one, too. I’ll skip it

  • This looks a little bit interesting, and the main course of the day should be that it can’t go wrong, so let’s move on

  • We can vaguely guess that this method is looking for a healthy Internet connection, so let’s move on

  • Do you feel a little confused? Let’s look at the comments above the method first

  • Combined with the source code and comments, we can tell that it will look for connections from the pool, and if it pulls out unhealthy connections, it will keep looking until it finds a healthy one.

  • Which begs the question, what kind of connections are unhealthy?

  • Let’s see what this code does. Okay

  • As an added bonus, OkHttp is implemented on sockets, not HttpURLConnection. This is the benefit of looking at the source code. The original OkHttp implementation is directly based on sockets.

  • That’s just an aside, but let’s see what are these three judgments?

  • An unhealthy stream is one where the Socket connection is closed or the input/output connection is closed

  • Let’s go back and see how it finds connections, okay?

  • This method demultiplexes an existing connection first, and creates a new connection last if it fails or does not exist

  • As you can see, this method takes a connection from the connection pool and looks at the source code

  • It iterates through the pool to determine whether the connection meets the requirements. If the connection meets the requirements, it directly assigns a value to the Connection field of the StreamAllocation object and returns the value. If the connection does not meet the requirements, it continues to iterate

  • So the question is, under what circumstances does it fit the bill?

  • If the connection object does not support transport, then it is not compliant

  • If the configuration of the connection is inconsistent with the requirements (except for the host address mismatch), then it is also inconsistent with the requirements

  • If the host address is consistent, then all parameters match and the connection can be reused

  • If the host address is different, what else do you need to determine? Let’s move on

  • If the connection does not support the Http 2.0 protocol, then the multiplexing connection is not supported

  • The next step is to determine whether the two routes match, so the question is, what is a route? What’s the use?

In fact, there are two parts, one is the HTTP proxy server address, and the other is the IP address resolved by DNS. Because HTTP proxy servers can have multiple, and THE DNS can also resolve multiple IP addresses, a route is needed to combine the two. For example, if the proxy server has A and B, and the DNS address has 1 and 2, four routes are generated, namely A1, A2, B1, and B2. The function of proxy server is, for example, we can not access Google normally, but we can use VPN. The VPN is the proxy server, and the overseas proxy server will access the website for us and return the data to us. The IP address heap resolved by DNS is used to switch to the next IP address when the host at one IP address is unreachable.

  • This determines whether the proxy is enabled, if not, the connection cannot be reused

  • If the proxy server is enabled but the address of the proxy server is different, the connection cannot be reused

  • If the Host address on the certificate is inconsistent with the Host address requested, the connection cannot be reused

  • Based on these information, we can conclude that the connection objects taken out from the connection pool cannot be reused directly, but can only be reused if certain conditions are met. The reused connection must match some information of the connection requested by the current user.

  • Having looked at this part of the source code, let’s go back to the previous source code

  • If a suitable connection object is found from the pool, it is returned directly to the upper layer. If not, what?

  • It gets a list of routes and distributes them to the connection pool to see if there are any matching connections

  • What if you still don’t find a connection object that meets your requirements? Let’s move on

  • If a connection object is found that matches the requirements, it is directly returned, otherwise a new connection object is created, and TCP three-way handshake and Https authentication are performed

  • Finally, the new connection object is added to the connection pool for later use

Source summary

  • The main purpose of this interceptor is to retrieve healthy connections from the connection pool (determine whether the Socket transport channel of the connection is available). If no connection is found in the connection pool that is eligible for reuse (all information except the host address must match, such as DNS, proxy, protocol, certificate), You will use the routing to find it again (the structure of routing is a proxy server address + an IP address in DNS), if still not, then can create a new connection object directly and three-way handshake, then add the new connection object to the connection pool, finally will return to back reusable connection.

Next up:OkHttp: CallServerInterceptor