1 /*
2  * Copyright (C) 2012 Square, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package okhttp3;
17
18 import java.net.Proxy;
19 import java.net.ProxySelector;
20 import java.net.Socket;
21 import java.security.GeneralSecurityException;
22 import java.time.Duration;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Random;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.TimeUnit;
29 import javax.annotation.Nullable;
30 import javax.net.SocketFactory;
31 import javax.net.ssl.HostnameVerifier;
32 import javax.net.ssl.SSLContext;
33 import javax.net.ssl.SSLSocket;
34 import javax.net.ssl.SSLSocketFactory;
35 import javax.net.ssl.TrustManager;
36 import javax.net.ssl.X509TrustManager;
37 import okhttp3.internal.Internal;
38 import okhttp3.internal.Util;
39 import okhttp3.internal.cache.InternalCache;
40 import okhttp3.internal.connection.Exchange;
41 import okhttp3.internal.connection.RealConnectionPool;
42 import okhttp3.internal.platform.Platform;
43 import okhttp3.internal.proxy.NullProxySelector;
44 import okhttp3.internal.tls.CertificateChainCleaner;
45 import okhttp3.internal.tls.OkHostnameVerifier;
46 import okhttp3.internal.ws.RealWebSocket;
47 import okio.Sink;
48 import okio.Source;
49 import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
50
51 import static okhttp3.internal.Util.checkDuration;
52
53 /**
54  * Factory for {@linkplain Call calls}, which can be used to send HTTP requests and read their
55  * responses.
56  *
57  * <h3>OkHttpClients should be shared</h3>
58  *
59  * <p>OkHttp performs best when you create a single {@code OkHttpClient} instance and reuse it for
60  * all of your HTTP calls. This is because each client holds its own connection pool and thread
61  * pools. Reusing connections and threads reduces latency and saves memory. Conversely, creating a
62  * client for each request wastes resources on idle pools.
63  *
64  * <p>Use {@code new OkHttpClient()} to create a shared instance with the default settings:
65  * <pre>   {@code
66  *
67  *   // The singleton HTTP client.
68  *   public final OkHttpClient client = new OkHttpClient();
69  * }</pre>
70  *
71  * <p>Or use {@code new OkHttpClient.Builder()} to create a shared instance with custom settings:
72  * <pre>   {@code
73  *
74  *   // The singleton HTTP client.
75  *   public final OkHttpClient client = new OkHttpClient.Builder()
76  *       .addInterceptor(new HttpLoggingInterceptor())
77  *       .cache(new Cache(cacheDir, cacheSize))
78  *       .build();
79  * }</pre>
80  *
81  * <h3>Customize your client with newBuilder()</h3>
82  *
83  * <p>You can customize a shared OkHttpClient instance with {@link #newBuilder()}. This builds a
84  * client that shares the same connection pool, thread pools, and configuration. Use the builder
85  * methods to configure the derived client for a specific purpose.
86  *
87  * <p>This example shows a call with a short 500 millisecond timeout: <pre>   {@code
88  *
89  *   OkHttpClient eagerClient = client.newBuilder()
90  *       .readTimeout(500, TimeUnit.MILLISECONDS)
91  *       .build();
92  *   Response response = eagerClient.newCall(request).execute();
93  * }</pre>
94  *
95  * <h3>Shutdown isn't necessary</h3>
96  *
97  * <p>The threads and connections that are held will be released automatically if they remain idle.
98  * But if you are writing a application that needs to aggressively release unused resources you may
99  * do so.
100  *
101  * <p>Shutdown the dispatcher's executor service with {@link ExecutorService#shutdown shutdown()}.
102  * This will also cause future calls to the client to be rejected. <pre>   {@code
103  *
104  *     client.dispatcher().executorService().shutdown();
105  * }</pre>
106  *
107  * <p>Clear the connection pool with {@link ConnectionPool#evictAll() evictAll()}. Note that the
108  * connection pool's daemon thread may not exit immediately. <pre>   {@code
109  *
110  *     client.connectionPool().evictAll();
111  * }</pre>
112  *
113  * <p>If your client has a cache, call {@link Cache#close close()}. Note that it is an error to
114  * create calls against a cache that is closed, and doing so will cause the call to crash.
115  * <pre>   {@code
116  *
117  *     client.cache().close();
118  * }</pre>
119  *
120  * <p>OkHttp also uses daemon threads for HTTP/2 connections. These will exit automatically if they
121  * remain idle.
122  */

123 public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
124   static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
125       Protocol.HTTP_2, Protocol.HTTP_1_1);
126
127   static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
128       ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT);
129
130   static {
131     Internal.instance = new Internal() {
132       @Override public void addLenient(Headers.Builder builder, String line) {
133         builder.addLenient(line);
134       }
135
136       @Override public void addLenient(Headers.Builder builder, String name, String value) {
137         builder.addLenient(name, value);
138       }
139
140       @Override public RealConnectionPool realConnectionPool(ConnectionPool connectionPool) {
141         return connectionPool.delegate;
142       }
143
144       @Override public boolean equalsNonHost(Address a, Address b) {
145         return a.equalsNonHost(b);
146       }
147
148       @Override public int code(Response.Builder responseBuilder) {
149         return responseBuilder.code;
150       }
151
152       @Override
153       public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
154         tlsConfiguration.apply(sslSocket, isFallback);
155       }
156
157       @Override public Call newWebSocketCall(OkHttpClient client, Request originalRequest) {
158         return RealCall.newRealCall(client, originalRequest, true);
159       }
160
161       @Override public void initExchange(
162           Response.Builder responseBuilder, Exchange exchange) {
163         responseBuilder.initExchange(exchange);
164       }
165
166       @Override public @Nullable Exchange exchange(Response response) {
167         return response.exchange;
168       }
169     };
170   }
171
172   final Dispatcher dispatcher;
173   final @Nullable Proxy proxy;
174   final List<Protocol> protocols;
175   final List<ConnectionSpec> connectionSpecs;
176   final List<Interceptor> interceptors;
177   final List<Interceptor> networkInterceptors;
178   final EventListener.Factory eventListenerFactory;
179   final ProxySelector proxySelector;
180   final CookieJar cookieJar;
181   final @Nullable Cache cache;
182   final @Nullable InternalCache internalCache;
183   final SocketFactory socketFactory;
184   final SSLSocketFactory sslSocketFactory;
185   final CertificateChainCleaner certificateChainCleaner;
186   final HostnameVerifier hostnameVerifier;
187   final CertificatePinner certificatePinner;
188   final Authenticator proxyAuthenticator;
189   final Authenticator authenticator;
190   final ConnectionPool connectionPool;
191   final Dns dns;
192   final boolean followSslRedirects;
193   final boolean followRedirects;
194   final boolean retryOnConnectionFailure;
195   final int callTimeout;
196   final int connectTimeout;
197   final int readTimeout;
198   final int writeTimeout;
199   final int pingInterval;
200
201   public OkHttpClient() {
202     this(new Builder());
203   }
204
205   OkHttpClient(Builder builder) {
206     this.dispatcher = builder.dispatcher;
207     this.proxy = builder.proxy;
208     this.protocols = builder.protocols;
209     this.connectionSpecs = builder.connectionSpecs;
210     this.interceptors = Util.immutableList(builder.interceptors);
211     this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
212     this.eventListenerFactory = builder.eventListenerFactory;
213     this.proxySelector = builder.proxySelector;
214     this.cookieJar = builder.cookieJar;
215     this.cache = builder.cache;
216     this.internalCache = builder.internalCache;
217     this.socketFactory = builder.socketFactory;
218
219     boolean isTLS = false;
220     for (ConnectionSpec spec : connectionSpecs) {
221       isTLS = isTLS || spec.isTls();
222     }
223
224     if (builder.sslSocketFactory != null || !isTLS) {
225       this.sslSocketFactory = builder.sslSocketFactory;
226       this.certificateChainCleaner = builder.certificateChainCleaner;
227     } else {
228       X509TrustManager trustManager = Util.platformTrustManager();
229       this.sslSocketFactory = newSslSocketFactory(trustManager);
230       this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
231     }
232
233     if (sslSocketFactory != null) {
234       Platform.get().configureSslSocketFactory(sslSocketFactory);
235     }
236
237     this.hostnameVerifier = builder.hostnameVerifier;
238     this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
239         certificateChainCleaner);
240     this.proxyAuthenticator = builder.proxyAuthenticator;
241     this.authenticator = builder.authenticator;
242     this.connectionPool = builder.connectionPool;
243     this.dns = builder.dns;
244     this.followSslRedirects = builder.followSslRedirects;
245     this.followRedirects = builder.followRedirects;
246     this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
247     this.callTimeout = builder.callTimeout;
248     this.connectTimeout = builder.connectTimeout;
249     this.readTimeout = builder.readTimeout;
250     this.writeTimeout = builder.writeTimeout;
251     this.pingInterval = builder.pingInterval;
252
253     if (interceptors.contains(null)) {
254       throw new IllegalStateException("Null interceptor: " + interceptors);
255     }
256     if (networkInterceptors.contains(null)) {
257       throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
258     }
259   }
260
261   private static SSLSocketFactory newSslSocketFactory(X509TrustManager trustManager) {
262     try {
263       SSLContext sslContext = Platform.get().getSSLContext();
264       sslContext.init(nullnew TrustManager[] { trustManager }, null);
265       return sslContext.getSocketFactory();
266     } catch (GeneralSecurityException e) {
267       throw new AssertionError("No System TLS", e); // The system has no TLS. Just give up.
268     }
269   }
270
271   /**
272    * Default call timeout (in milliseconds). By default there is no timeout for complete calls, but
273    * there is for the connect, write, and read actions within a call.
274    */

275   public int callTimeoutMillis() {
276     return callTimeout;
277   }
278
279   /** Default connect timeout (in milliseconds). The default is 10 seconds. */
280   public int connectTimeoutMillis() {
281     return connectTimeout;
282   }
283
284   /** Default read timeout (in milliseconds). The default is 10 seconds. */
285   public int readTimeoutMillis() {
286     return readTimeout;
287   }
288
289   /** Default write timeout (in milliseconds). The default is 10 seconds. */
290   public int writeTimeoutMillis() {
291     return writeTimeout;
292   }
293
294   /** Web socket and HTTP/2 ping interval (in milliseconds). By default pings are not sent. */
295   public int pingIntervalMillis() {
296     return pingInterval;
297   }
298
299   public @Nullable Proxy proxy() {
300     return proxy;
301   }
302
303   public ProxySelector proxySelector() {
304     return proxySelector;
305   }
306
307   public CookieJar cookieJar() {
308     return cookieJar;
309   }
310
311   public @Nullable Cache cache() {
312     return cache;
313   }
314
315   @Nullable InternalCache internalCache() {
316     return cache != null ? cache.internalCache : internalCache;
317   }
318
319   public Dns dns() {
320     return dns;
321   }
322
323   public SocketFactory socketFactory() {
324     return socketFactory;
325   }
326
327   public SSLSocketFactory sslSocketFactory() {
328     return sslSocketFactory;
329   }
330
331   public HostnameVerifier hostnameVerifier() {
332     return hostnameVerifier;
333   }
334
335   public CertificatePinner certificatePinner() {
336     return certificatePinner;
337   }
338
339   public Authenticator authenticator() {
340     return authenticator;
341   }
342
343   public Authenticator proxyAuthenticator() {
344     return proxyAuthenticator;
345   }
346
347   public ConnectionPool connectionPool() {
348     return connectionPool;
349   }
350
351   public boolean followSslRedirects() {
352     return followSslRedirects;
353   }
354
355   public boolean followRedirects() {
356     return followRedirects;
357   }
358
359   public boolean retryOnConnectionFailure() {
360     return retryOnConnectionFailure;
361   }
362
363   public Dispatcher dispatcher() {
364     return dispatcher;
365   }
366
367   public List<Protocol> protocols() {
368     return protocols;
369   }
370
371   public List<ConnectionSpec> connectionSpecs() {
372     return connectionSpecs;
373   }
374
375   /**
376    * Returns an immutable list of interceptors that observe the full span of each call: from before
377    * the connection is established (if any) until after the response source is selected (either the
378    * origin server, cache, or both).
379    */

380   public List<Interceptor> interceptors() {
381     return interceptors;
382   }
383
384   /**
385    * Returns an immutable list of interceptors that observe a single network request and response.
386    * These interceptors must call {@link Interceptor.Chain#proceed} exactly once: it is an error for
387    * a network interceptor to short-circuit or repeat a network request.
388    */

389   public List<Interceptor> networkInterceptors() {
390     return networkInterceptors;
391   }
392
393   public EventListener.Factory eventListenerFactory() {
394     return eventListenerFactory;
395   }
396
397   /**
398    * Prepares the {@code request} to be executed at some point in the future.
399    */

400   @Override public Call newCall(Request request) {
401     return RealCall.newRealCall(this, request, false /* for web socket */);
402   }
403
404   /**
405    * Uses {@code request} to connect a new web socket.
406    */

407   @Override public WebSocket newWebSocket(Request request, WebSocketListener listener) {
408     RealWebSocket webSocket = new RealWebSocket(request, listener, new Random(), pingInterval);
409     webSocket.connect(this);
410     return webSocket;
411   }
412
413   public Builder newBuilder() {
414     return new Builder(this);
415   }
416
417   public static final class Builder {
418     Dispatcher dispatcher;
419     @Nullable Proxy proxy;
420     List<Protocol> protocols;
421     List<ConnectionSpec> connectionSpecs;
422     final List<Interceptor> interceptors = new ArrayList<>();
423     final List<Interceptor> networkInterceptors = new ArrayList<>();
424     EventListener.Factory eventListenerFactory;
425     ProxySelector proxySelector;
426     CookieJar cookieJar;
427     @Nullable Cache cache;
428     @Nullable InternalCache internalCache;
429     SocketFactory socketFactory;
430     @Nullable SSLSocketFactory sslSocketFactory;
431     @Nullable CertificateChainCleaner certificateChainCleaner;
432     HostnameVerifier hostnameVerifier;
433     CertificatePinner certificatePinner;
434     Authenticator proxyAuthenticator;
435     Authenticator authenticator;
436     ConnectionPool connectionPool;
437     Dns dns;
438     boolean followSslRedirects;
439     boolean followRedirects;
440     boolean retryOnConnectionFailure;
441     int callTimeout;
442     int connectTimeout;
443     int readTimeout;
444     int writeTimeout;
445     int pingInterval;
446
447     public Builder() {
448       dispatcher = new Dispatcher();
449       protocols = DEFAULT_PROTOCOLS;
450       connectionSpecs = DEFAULT_CONNECTION_SPECS;
451       eventListenerFactory = EventListener.factory(EventListener.NONE);
452       proxySelector = ProxySelector.getDefault();
453       if (proxySelector == null) {
454         proxySelector = new NullProxySelector();
455       }
456       cookieJar = CookieJar.NO_COOKIES;
457       socketFactory = SocketFactory.getDefault();
458       hostnameVerifier = OkHostnameVerifier.INSTANCE;
459       certificatePinner = CertificatePinner.DEFAULT;
460       proxyAuthenticator = Authenticator.NONE;
461       authenticator = Authenticator.NONE;
462       connectionPool = new ConnectionPool();
463       dns = Dns.SYSTEM;
464       followSslRedirects = true;
465       followRedirects = true;
466       retryOnConnectionFailure = true;
467       callTimeout = 0;
468       connectTimeout = 10_000;
469       readTimeout = 10_000;
470       writeTimeout = 10_000;
471       pingInterval = 0;
472     }
473
474     Builder(OkHttpClient okHttpClient) {
475       this.dispatcher = okHttpClient.dispatcher;
476       this.proxy = okHttpClient.proxy;
477       this.protocols = okHttpClient.protocols;
478       this.connectionSpecs = okHttpClient.connectionSpecs;
479       this.interceptors.addAll(okHttpClient.interceptors);
480       this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
481       this.eventListenerFactory = okHttpClient.eventListenerFactory;
482       this.proxySelector = okHttpClient.proxySelector;
483       this.cookieJar = okHttpClient.cookieJar;
484       this.internalCache = okHttpClient.internalCache;
485       this.cache = okHttpClient.cache;
486       this.socketFactory = okHttpClient.socketFactory;
487       this.sslSocketFactory = okHttpClient.sslSocketFactory;
488       this.certificateChainCleaner = okHttpClient.certificateChainCleaner;
489       this.hostnameVerifier = okHttpClient.hostnameVerifier;
490       this.certificatePinner = okHttpClient.certificatePinner;
491       this.proxyAuthenticator = okHttpClient.proxyAuthenticator;
492       this.authenticator = okHttpClient.authenticator;
493       this.connectionPool = okHttpClient.connectionPool;
494       this.dns = okHttpClient.dns;
495       this.followSslRedirects = okHttpClient.followSslRedirects;
496       this.followRedirects = okHttpClient.followRedirects;
497       this.retryOnConnectionFailure = okHttpClient.retryOnConnectionFailure;
498       this.callTimeout = okHttpClient.callTimeout;
499       this.connectTimeout = okHttpClient.connectTimeout;
500       this.readTimeout = okHttpClient.readTimeout;
501       this.writeTimeout = okHttpClient.writeTimeout;
502       this.pingInterval = okHttpClient.pingInterval;
503     }
504
505     /**
506      * Sets the default timeout for complete calls. A value of 0 means no timeout, otherwise values
507      * must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
508      *
509      * <p>The call timeout spans the entire call: resolving DNS, connecting, writing the request
510      * body, server processing, and reading the response body. If the call requires redirects or
511      * retries all must complete within one timeout period.
512      *
513      * <p>The default value is 0 which imposes no timeout.
514      */

515     public Builder callTimeout(long timeout, TimeUnit unit) {
516       callTimeout = checkDuration("timeout", timeout, unit);
517       return this;
518     }
519
520     /**
521      * Sets the default timeout for complete calls. A value of 0 means no timeout, otherwise values
522      * must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
523      *
524      * <p>The call timeout spans the entire call: resolving DNS, connecting, writing the request
525      * body, server processing, and reading the response body. If the call requires redirects or
526      * retries all must complete within one timeout period.
527      *
528      * <p>The default value is 0 which imposes no timeout.
529      */

530     @IgnoreJRERequirement
531     public Builder callTimeout(Duration duration) {
532       callTimeout = checkDuration("timeout", duration.toMillis(), TimeUnit.MILLISECONDS);
533       return this;
534     }
535
536     /**
537      * Sets the default connect timeout for new connections. A value of 0 means no timeout,
538      * otherwise values must be between 1 and {@link Integer#MAX_VALUE} when converted to
539      * milliseconds.
540      *
541      * <p>The connect timeout is applied when connecting a TCP socket to the target host.
542      * The default value is 10 seconds.
543      */

544     public Builder connectTimeout(long timeout, TimeUnit unit) {
545       connectTimeout = checkDuration("timeout", timeout, unit);
546       return this;
547     }
548
549     /**
550      * Sets the default connect timeout for new connections. A value of 0 means no timeout,
551      * otherwise values must be between 1 and {@link Integer#MAX_VALUE} when converted to
552      * milliseconds.
553      *
554      * <p>The connect timeout is applied when connecting a TCP socket to the target host.
555      * The default value is 10 seconds.
556      */

557     @IgnoreJRERequirement
558     public Builder connectTimeout(Duration duration) {
559       connectTimeout = checkDuration("timeout", duration.toMillis(), TimeUnit.MILLISECONDS);
560       return this;
561     }
562
563     /**
564      * Sets the default read timeout for new connections. A value of 0 means no timeout, otherwise
565      * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
566      *
567      * <p>The read timeout is applied to both the TCP socket and for individual read IO operations
568      * including on {@link Source} of the {@link Response}. The default value is 10 seconds.
569      *
570      * @see Socket#setSoTimeout(int)
571      * @see Source#timeout()
572      */

573     public Builder readTimeout(long timeout, TimeUnit unit) {
574       readTimeout = checkDuration("timeout", timeout, unit);
575       return this;
576     }
577
578     /**
579      * Sets the default read timeout for new connections. A value of 0 means no timeout, otherwise
580      * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
581      *
582      * <p>The read timeout is applied to both the TCP socket and for individual read IO operations
583      * including on {@link Source} of the {@link Response}. The default value is 10 seconds.
584      *
585      * @see Socket#setSoTimeout(int)
586      * @see Source#timeout()
587      */

588     @IgnoreJRERequirement
589     public Builder readTimeout(Duration duration) {
590       readTimeout = checkDuration("timeout", duration.toMillis(), TimeUnit.MILLISECONDS);
591       return this;
592     }
593
594     /**
595      * Sets the default write timeout for new connections. A value of 0 means no timeout, otherwise
596      * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
597      *
598      * <p>The write timeout is applied for individual write IO operations.
599      * The default value is 10 seconds.
600      *
601      * @see Sink#timeout()
602      */

603     public Builder writeTimeout(long timeout, TimeUnit unit) {
604       writeTimeout = checkDuration("timeout", timeout, unit);
605       return this;
606     }
607
608     /**
609      * Sets the default write timeout for new connections. A value of 0 means no timeout, otherwise
610      * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
611      *
612      * <p>The write timeout is applied for individual write IO operations.
613      * The default value is 10 seconds.
614      *
615      * @see Sink#timeout()
616      */

617     @IgnoreJRERequirement
618     public Builder writeTimeout(Duration duration) {
619       writeTimeout = checkDuration("timeout", duration.toMillis(), TimeUnit.MILLISECONDS);
620       return this;
621     }
622
623     /**
624      * Sets the interval between HTTP/2 and web socket pings initiated by this client. Use this to
625      * automatically send ping frames until either the connection fails or it is closed. This keeps
626      * the connection alive and may detect connectivity failures.
627      *
628      * <p>If the server does not respond to each ping with a pong within {@code interval}, this
629      * client will assume that connectivity has been lost. When this happens on a web socket the
630      * connection is canceled and its listener is {@linkplain WebSocketListener#onFailure notified
631      * of the failure}. When it happens on an HTTP/2 connection the connection is closed and any
632      * calls it is carrying {@linkplain java.io.IOException will fail with an IOException}.
633      *
634      * <p>The default value of 0 disables client-initiated pings.
635      */

636     public Builder pingInterval(long interval, TimeUnit unit) {
637       pingInterval = checkDuration("interval", interval, unit);
638       return this;
639     }
640
641     /**
642      * Sets the interval between HTTP/2 and web socket pings initiated by this client. Use this to
643      * automatically send ping frames until either the connection fails or it is closed. This keeps
644      * the connection alive and may detect connectivity failures.
645      *
646      * <p>If the server does not respond to each ping with a pong within {@code interval}, this
647      * client will assume that connectivity has been lost. When this happens on a web socket the
648      * connection is canceled and its listener is {@linkplain WebSocketListener#onFailure notified
649      * of the failure}. When it happens on an HTTP/2 connection the connection is closed and any
650      * calls it is carrying {@linkplain java.io.IOException will fail with an IOException}.
651      *
652      * <p>The default value of 0 disables client-initiated pings.
653      */

654     @IgnoreJRERequirement
655     public Builder pingInterval(Duration duration) {
656       pingInterval = checkDuration("timeout", duration.toMillis(), TimeUnit.MILLISECONDS);
657       return this;
658     }
659
660     /**
661      * Sets the HTTP proxy that will be used by connections created by this client. This takes
662      * precedence over {@link #proxySelector}, which is only honored when this proxy is null (which
663      * it is by default). To disable proxy use completely, call {@code proxy(Proxy.NO_PROXY)}.
664      */

665     public Builder proxy(@Nullable Proxy proxy) {
666       this.proxy = proxy;
667       return this;
668     }
669
670     /**
671      * Sets the proxy selection policy to be used if no {@link #proxy proxy} is specified
672      * explicitly. The proxy selector may return multiple proxies; in that case they will be tried
673      * in sequence until a successful connection is established.
674      *
675      * <p>If unset, the {@link ProxySelector#getDefault() system-wide default} proxy selector will
676      * be used.
677      */

678     public Builder proxySelector(ProxySelector proxySelector) {
679       if (proxySelector == nullthrow new NullPointerException("proxySelector == null");
680       this.proxySelector = proxySelector;
681       return this;
682     }
683
684     /**
685      * Sets the handler that can accept cookies from incoming HTTP responses and provides cookies to
686      * outgoing HTTP requests.
687      *
688      * <p>If unset, {@linkplain CookieJar#NO_COOKIES no cookies} will be accepted nor provided.
689      */

690     public Builder cookieJar(CookieJar cookieJar) {
691       if (cookieJar == nullthrow new NullPointerException("cookieJar == null");
692       this.cookieJar = cookieJar;
693       return this;
694     }
695
696     /** Sets the response cache to be used to read and write cached responses. */
697     public Builder cache(@Nullable Cache cache) {
698       this.cache = cache;
699       this.internalCache = null;
700       return this;
701     }
702
703     /**
704      * Sets the DNS service used to lookup IP addresses for hostnames.
705      *
706      * <p>If unset, the {@link Dns#SYSTEM system-wide default} DNS will be used.
707      */

708     public Builder dns(Dns dns) {
709       if (dns == nullthrow new NullPointerException("dns == null");
710       this.dns = dns;
711       return this;
712     }
713
714     /**
715      * Sets the socket factory used to create connections. OkHttp only uses the parameterless {@link
716      * SocketFactory#createSocket() createSocket()} method to create unconnected sockets. Overriding
717      * this method, e. g., allows the socket to be bound to a specific local address.
718      *
719      * <p>If unset, the {@link SocketFactory#getDefault() system-wide default} socket factory will
720      * be used.
721      */

722     public Builder socketFactory(SocketFactory socketFactory) {
723       if (socketFactory == nullthrow new NullPointerException("socketFactory == null");
724       if (socketFactory instanceof SSLSocketFactory) {
725         throw new IllegalArgumentException("socketFactory instanceof SSLSocketFactory");
726       }
727       this.socketFactory = socketFactory;
728       return this;
729     }
730
731     /**
732      * Sets the socket factory used to secure HTTPS connections. If unset, the system default will
733      * be used.
734      *
735      * @deprecated {@code SSLSocketFactory} does not expose its {@link X509TrustManager}, which is
736      *     a field that OkHttp needs to build a clean certificate chain. This method instead must
737      *     use reflection to extract the trust manager. Applications should prefer to call {@link
738      *     #sslSocketFactory(SSLSocketFactory, X509TrustManager)}, which avoids such reflection.
739      */

740     public Builder sslSocketFactory(SSLSocketFactory sslSocketFactory) {
741       if (sslSocketFactory == nullthrow new NullPointerException("sslSocketFactory == null");
742       this.sslSocketFactory = sslSocketFactory;
743       this.certificateChainCleaner = Platform.get().buildCertificateChainCleaner(sslSocketFactory);
744       return this;
745     }
746
747     /**
748      * Sets the socket factory and trust manager used to secure HTTPS connections. If unset, the
749      * system defaults will be used.
750      *
751      * <p>Most applications should not call this method, and instead use the system defaults. Those
752      * classes include special optimizations that can be lost if the implementations are decorated.
753      *
754      * <p>If necessary, you can create and configure the defaults yourself with the following code:
755      *
756      * <pre>   {@code
757      *
758      *   TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
759      *       TrustManagerFactory.getDefaultAlgorithm());
760      *   trustManagerFactory.init((KeyStore) null);
761      *   TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
762      *   if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
763      *     throw new IllegalStateException("Unexpected default trust managers:"
764      *         + Arrays.toString(trustManagers));
765      *   }
766      *   X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
767      *
768      *   SSLContext sslContext = SSLContext.getInstance("TLS");
769      *   sslContext.init(nullnew TrustManager[] { trustManager }, null);
770      *   SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
771      *
772      *   OkHttpClient client = new OkHttpClient.Builder()
773      *       .sslSocketFactory(sslSocketFactory, trustManager)
774      *       .build();
775      * }</pre>
776      */

777     public Builder sslSocketFactory(
778         SSLSocketFactory sslSocketFactory, X509TrustManager trustManager) {
779       if (sslSocketFactory == nullthrow new NullPointerException("sslSocketFactory == null");
780       if (trustManager == nullthrow new NullPointerException("trustManager == null");
781       this.sslSocketFactory = sslSocketFactory;
782       this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
783       return this;
784     }
785
786     /**
787      * Sets the verifier used to confirm that response certificates apply to requested hostnames for
788      * HTTPS connections.
789      *
790      * <p>If unset, a default hostname verifier will be used.
791      */

792     public Builder hostnameVerifier(HostnameVerifier hostnameVerifier) {
793       if (hostnameVerifier == nullthrow new NullPointerException("hostnameVerifier == null");
794       this.hostnameVerifier = hostnameVerifier;
795       return this;
796     }
797
798     /**
799      * Sets the certificate pinner that constrains which certificates are trusted. By default HTTPS
800      * connections rely on only the {@link #sslSocketFactory SSL socket factory} to establish trust.
801      * Pinning certificates avoids the need to trust certificate authorities.
802      */

803     public Builder certificatePinner(CertificatePinner certificatePinner) {
804       if (certificatePinner == nullthrow new NullPointerException("certificatePinner == null");
805       this.certificatePinner = certificatePinner;
806       return this;
807     }
808
809     /**
810      * Sets the authenticator used to respond to challenges from origin servers. Use {@link
811      * #proxyAuthenticator} to set the authenticator for proxy servers.
812      *
813      * <p>If unset, the {@linkplain Authenticator#NONE no authentication will be attempted}.
814      */

815     public Builder authenticator(Authenticator authenticator) {
816       if (authenticator == nullthrow new NullPointerException("authenticator == null");
817       this.authenticator = authenticator;
818       return this;
819     }
820
821     /**
822      * Sets the authenticator used to respond to challenges from proxy servers. Use {@link
823      * #authenticator} to set the authenticator for origin servers.
824      *
825      * <p>If unset, the {@linkplain Authenticator#NONE no authentication will be attempted}.
826      */

827     public Builder proxyAuthenticator(Authenticator proxyAuthenticator) {
828       if (proxyAuthenticator == nullthrow new NullPointerException("proxyAuthenticator == null");
829       this.proxyAuthenticator = proxyAuthenticator;
830       return this;
831     }
832
833     /**
834      * Sets the connection pool used to recycle HTTP and HTTPS connections.
835      *
836      * <p>If unset, a new connection pool will be used.
837      */

838     public Builder connectionPool(ConnectionPool connectionPool) {
839       if (connectionPool == nullthrow new NullPointerException("connectionPool == null");
840       this.connectionPool = connectionPool;
841       return this;
842     }
843
844     /**
845      * Configure this client to follow redirects from HTTPS to HTTP and from HTTP to HTTPS.
846      *
847      * <p>If unset, protocol redirects will be followed. This is different than the built-in {@code
848      * HttpURLConnection}'s default.
849      */

850     public Builder followSslRedirects(boolean followProtocolRedirects) {
851       this.followSslRedirects = followProtocolRedirects;
852       return this;
853     }
854
855     /** Configure this client to follow redirects. If unset, redirects will be followed. */
856     public Builder followRedirects(boolean followRedirects) {
857       this.followRedirects = followRedirects;
858       return this;
859     }
860
861     /**
862      * Configure this client to retry or not when a connectivity problem is encountered. By default,
863      * this client silently recovers from the following problems:
864      *
865      * <ul>
866      *   <li><strong>Unreachable IP addresses.</strong> If the URL's host has multiple IP addresses,
867      *       failure to reach any individual IP address doesn't fail the overall request. This can
868      *       increase availability of multi-homed services.
869      *   <li><strong>Stale pooled connections.</strong> The {@link ConnectionPool} reuses sockets
870      *       to decrease request latency, but these connections will occasionally time out.
871      *   <li><strong>Unreachable proxy servers.</strong> A {@link ProxySelector} can be used to
872      *       attempt multiple proxy servers in sequence, eventually falling back to a direct
873      *       connection.
874      * </ul>
875      *
876      * Set this to false to avoid retrying requests when doing so is destructive. In this case the
877      * calling application should do its own recovery of connectivity failures.
878      */

879     public Builder retryOnConnectionFailure(boolean retryOnConnectionFailure) {
880       this.retryOnConnectionFailure = retryOnConnectionFailure;
881       return this;
882     }
883
884     /**
885      * Sets the dispatcher used to set policy and execute asynchronous requests. Must not be null.
886      */

887     public Builder dispatcher(Dispatcher dispatcher) {
888       if (dispatcher == nullthrow new IllegalArgumentException("dispatcher == null");
889       this.dispatcher = dispatcher;
890       return this;
891     }
892
893     /**
894      * Configure the protocols used by this client to communicate with remote servers. By default
895      * this client will prefer the most efficient transport available, falling back to more
896      * ubiquitous protocols. Applications should only call this method to avoid specific
897      * compatibility problems, such as web servers that behave incorrectly when HTTP/2 is enabled.
898      *
899      * <p>The following protocols are currently supported:
900      *
901      * <ul>
902      *     <li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">http/1.1</a>
903      *     <li><a href="https://tools.ietf.org/html/rfc7540">h2</a>
904      *     <li><a href="https://tools.ietf.org/html/rfc7540#section-3.4">h2 with prior knowledge
905      *         (cleartext only)</a>
906      * </ul>
907      *
908      * <p><strong>This is an evolving set.</strong> Future releases include support for transitional
909      * protocols. The http/1.1 transport will never be dropped.
910      *
911      * <p>If multiple protocols are specified, <a
912      * href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg">ALPN</a> will be used to
913      * negotiate a transport. Protocol negotiation is only attempted for HTTPS URLs.
914      *
915      * <p>{@link Protocol#HTTP_1_0} is not supported in this set. Requests are initiated with {@code
916      * HTTP/1.1}. If the server responds with {@code HTTP/1.0}, that will be exposed by {@link
917      * Response#protocol()}.
918      *
919      * @param protocols the protocols to use, in order of preference. If the list contains {@link
920      *     Protocol#H2_PRIOR_KNOWLEDGE} then that must be the only protocol and HTTPS URLs will not
921      *     be supported. Otherwise the list must contain {@link Protocol#HTTP_1_1}. The list must
922      *     not contain null or {@link Protocol#HTTP_1_0}.
923      */

924     public Builder protocols(List<Protocol> protocols) {
925       // Create a private copy of the list.
926       protocols = new ArrayList<>(protocols);
927
928       // Validate that the list has everything we require and nothing we forbid.
929       if (!protocols.contains(Protocol.H2_PRIOR_KNOWLEDGE)
930           && !protocols.contains(Protocol.HTTP_1_1)) {
931         throw new IllegalArgumentException(
932             "protocols must contain h2_prior_knowledge or http/1.1: " + protocols);
933       }
934       if (protocols.contains(Protocol.H2_PRIOR_KNOWLEDGE) && protocols.size() > 1) {
935         throw new IllegalArgumentException(
936             "protocols containing h2_prior_knowledge cannot use other protocols: " + protocols);
937       }
938       if (protocols.contains(Protocol.HTTP_1_0)) {
939         throw new IllegalArgumentException("protocols must not contain http/1.0: " + protocols);
940       }
941       if (protocols.contains(null)) {
942         throw new IllegalArgumentException("protocols must not contain null");
943       }
944
945       // Remove protocols that we no longer support.
946       protocols.remove(Protocol.SPDY_3);
947
948       // Assign as an unmodifiable list. This is effectively immutable.
949       this.protocols = Collections.unmodifiableList(protocols);
950       return this;
951     }
952
953     public Builder connectionSpecs(List<ConnectionSpec> connectionSpecs) {
954       this.connectionSpecs = Util.immutableList(connectionSpecs);
955       return this;
956     }
957
958     /**
959      * Returns a modifiable list of interceptors that observe the full span of each call: from
960      * before the connection is established (if any) until after the response source is selected
961      * (either the origin server, cache, or both).
962      */

963     public List<Interceptor> interceptors() {
964       return interceptors;
965     }
966
967     public Builder addInterceptor(Interceptor interceptor) {
968       if (interceptor == nullthrow new IllegalArgumentException("interceptor == null");
969       interceptors.add(interceptor);
970       return this;
971     }
972
973     /**
974      * Returns a modifiable list of interceptors that observe a single network request and response.
975      * These interceptors must call {@link Interceptor.Chain#proceed} exactly once: it is an error
976      * for a network interceptor to short-circuit or repeat a network request.
977      */

978     public List<Interceptor> networkInterceptors() {
979       return networkInterceptors;
980     }
981
982     public Builder addNetworkInterceptor(Interceptor interceptor) {
983       if (interceptor == nullthrow new IllegalArgumentException("interceptor == null");
984       networkInterceptors.add(interceptor);
985       return this;
986     }
987
988     /**
989      * Configure a single client scoped listener that will receive all analytic events
990      * for this client.
991      *
992      * @see EventListener for semantics and restrictions on listener implementations.
993      */

994     public Builder eventListener(EventListener eventListener) {
995       if (eventListener == nullthrow new NullPointerException("eventListener == null");
996       this.eventListenerFactory = EventListener.factory(eventListener);
997       return this;
998     }
999
1000     /**
1001      * Configure a factory to provide per-call scoped listeners that will receive analytic events
1002      * for this client.
1003      *
1004      * @see EventListener for semantics and restrictions on listener implementations.
1005      */

1006     public Builder eventListenerFactory(EventListener.Factory eventListenerFactory) {
1007       if (eventListenerFactory == null) {
1008         throw new NullPointerException("eventListenerFactory == null");
1009       }
1010       this.eventListenerFactory = eventListenerFactory;
1011       return this;
1012     }
1013
1014     public OkHttpClient build() {
1015       return new OkHttpClient(this);
1016     }
1017   }
1018 }
1019