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(null, new 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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(null, new 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 == null) throw new NullPointerException("sslSocketFactory == null");
780 if (trustManager == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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 == null) throw 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