HTTP proxy: a proxy server may be explicitly configured for the client. Otherwise the {@linkplain java.net.ProxySelector proxy selector} is used. It may return multiple proxies to attempt.
IP address: whether connecting directly to an origin server or a proxy, opening a socket requires an IP address. The DNS server may return multiple IP addresses to attempt.
TLS configuration: which cipher suites and TLS versions to attempt with the HTTPS connection.
The sockets and streams of an HTTP, HTTPS, or HTTPS+SPDY connection. May be used for multiple HTTP request/response exchanges. Connections may be direct to the origin server or via a proxy.
Typically instances of this class are created, connected and exercised automatically by the HTTP client. Applications may use this class to monitor HTTP connections as members of a ConnectionPool.
Server Name Indication (SNI) enables one IP address to negotiate secure connections for multiple domain names.
SNI有效:一個IP位址用來協調多個域名的安全連接配接
Application Layer Protocol Negotiation (ALPN) enables the HTTPS port (443) to be used for different HTTP and SPDY protocols.
ALPN有效:443HTTPS端口可用于不同的HTTP和SPDY協定
Unfortunately, older HTTPS servers refuse to connect when such options are presented. Rather than avoiding these options entirely, this class allows a connection to be attempted with modern options and then retried without them should the attempt fail.
Manages reuse of HTTP and SPDY connections for reduced network latency. HTTP requests that share the same Address may share a Connection. This class implements the policy of which connections to keep open for future use.
The system-wide default uses system properties for tuning parameters:
http.maxConnections maximum number of idle connections to each to keep in the pool. Default is 5.
http.maxConnections 是連接配接池中保留的最大空閑連接配接數,預設為5
http.keepAliveDuration Time in milliseconds to keep the connection alive in the pool before closing it. Default is 5 minutes. This property isn’t used by HttpURLConnection.
The default instance doesn’t adjust its configuration as system properties are changed. This assumes that the applications that set these parameters do so before making HTTP connections, and that this class is initialized lazily.
An HTTP response. Instances of this class are not immutable: the response body is a one-shot value that may be consumed only once. All other properties are immutable.
A call is a request that has been prepared for execution. A call can be canceled. As this object represents a single request/response pair (stream), it cannot be executed twice.
Each dispatcher uses an ExecutorService to run calls internally. If you supply your own executor, it should be able to run configured maximum number of calls concurrently.
Handles a single HTTP request/response pair. Each HTTP engine follows this
lifecycle:
譯:處理單個Http請求/響應對,每一個Http引擎都遵循這個生命周期:
It is created.
建立
The HTTP request message is sent with sendRequest(). Once the request is sent it is an error to modify the request headers. After sendRequest() has been called the request body can be written to if it exists.
The HTTP response message is read with readResponse(). After the response has been read the response headers and body can be read. All responses have a response body input stream, though in some instances this stream is empty.
The request and response may be served by the HTTP response cache, by the network, or by both in the event of a conditional GET.
譯:請求和響應可以由http響應緩存,或者網絡,或者兩者都有,在Get情況下提供服務。
10.Internal.java
Escalate internal APIs in {@code com.squareup.okhttp} so they can be used from OkHttp’s implementation packages. The only implementation of this interface is in {@link com.squareup.okhttp.OkHttpClient}.
Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and bandwidth.
緩存HTTP和HTTPS對檔案系統的響應,進而可以重用,進而節省時間和帶寬。
Cache Optimization
To measure cache effectiveness, this class tracks three statistics:
譯:為了衡量緩存的有效性,該類跟蹤三個統計資訊:
Request Count: the number of HTTP requests issued since this cache was created.
請求計數:建立此緩存後發出的Http請求數
Network Count: the number of those requests that required network use.
網絡計數:需要網絡使用的請求數
Hit Count: the number of those requests whose responses were served by the cache.
命中計數:由緩存提供響應的請求數
Sometimes a request will result in a conditional cache hit. If the cache contains a stale copy of the response, the client will issue a conditional GET. The server will then send either the updated response if it has changed, or a short ‘not modified’ response if the client’s copy is still valid. Such responses increment both the network count and hit count.
The best way to improve the cache hit rate is by configuring the web server to return cacheable responses. Although this client honors all HTTP/1.1 (RFC 2068) cache headers, it doesn’t cache partial responses.
In some situations, such as after a user clicks a ‘refresh’ button, it may be necessary to skip the cache, and fetch data directly from the server. To force a full refresh, add the {@code no-cache} directive:
If it is only necessary to force a cached response to be validated by the server, use the more efficient {@code max-age=0} instead:
譯:如果僅需要強制緩存的響應由伺服器驗證,則使用更有效的{@code max-age = 0}:
Force a Cache Response
Sometimes you’ll want to show resources if they are available immediately, but not otherwise. This can be used so your application can show something while waiting for the latest data to be downloaded. To restrict a request to locally-cached resources, add the {@code only-if-cached} directive:
try {
connection.addRequestProperty("Cache-Control", "only-if-cached");
InputStream cached = connection.getInputStream();
// the resource was cached! show it
} catch (FileNotFoundException e) {
// the resource was not cached
}
This technique works even better in situations where a stale response is better than no response. To permit stale cached responses, use the {@code max-stale} directive with the maximum staleness in seconds:
int maxStale = * * * ; // tolerate 4-weeks stale
connection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
12.OkHttpClient.java
Configures and creates HTTP connections. Most applications can use a single OkHttpClient for all of their HTTP requests - benefiting from a shared response cache, thread pool, connection re-use, etc.
Instances of OkHttpClient are intended to be fully configured before they’re shared - once shared they should be treated as immutable and can safely be used to concurrently open new connections. If required, threads can call clone to make a shallow copy of the OkHttpClient that can be safely modified with further configuration changes.
public void sendRequest() throws IOException {
if (cacheStrategy != null) {
return; // Already sent.
}
if (transport != null) {
throw new IllegalStateException();
}
//填充預設的請求頭部和事務。
Request request = networkRequest(userRequest);
//下面一行很重要,這個方法會去擷取client中的Cache。同時Cache在初始化的時候會去讀取緩存目錄中關于曾經請求過的所有資訊。
InternalCache responseCache = Internal.instance.internalCache(client);
Response cacheCandidate = responseCache != null? responseCache.get(request): null;
long now = System.currentTimeMillis();
//緩存政策中的各種配置的封裝
cacheStrategy = new CacheStrategy.Factory(now, request, cacheCandidate).get();
networkRequest = cacheStrategy.networkRequest;
cacheResponse = cacheStrategy.cacheResponse;
if (responseCache != null) {
//記錄目前請求是來至網絡還是命中了緩存
responseCache.trackResponse(cacheStrategy);
}
if (cacheCandidate != null && cacheResponse == null) {
closeQuietly(cacheCandidate.body()); // The cache candidate wasn't applicable. Close it.
}
if (networkRequest != null) {
// Open a connection unless we inherited one from a redirect.
if (connection == null) {
//連接配接到伺服器、重定向伺服器或者通過一個代理Connect to the origin server either directly or via a proxy.
connect();
}
//通過Connection建立一個SpdyTransport或者HttpTransport
transport = Internal.instance.newTransport(connection, this);
...
} else {
...
}
}