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 com.squareup.okhttp;
17 
18 import com.squareup.okhttp.internal.Internal;
19 import com.squareup.okhttp.internal.InternalCache;
20 import com.squareup.okhttp.internal.Network;
21 import com.squareup.okhttp.internal.RouteDatabase;
22 import com.squareup.okhttp.internal.Util;
23 import com.squareup.okhttp.internal.http.AuthenticatorAdapter;
24 import com.squareup.okhttp.internal.http.HttpEngine;
25 import com.squareup.okhttp.internal.http.RouteException;
26 import com.squareup.okhttp.internal.http.Transport;
27 import com.squareup.okhttp.internal.tls.OkHostnameVerifier;
28 import java.io.IOException;
29 import java.net.CookieHandler;
30 import java.net.MalformedURLException;
31 import java.net.Proxy;
32 import java.net.ProxySelector;
33 import java.net.URLConnection;
34 import java.net.UnknownHostException;
35 import java.security.GeneralSecurityException;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.concurrent.TimeUnit;
39 import javax.net.SocketFactory;
40 import javax.net.ssl.HostnameVerifier;
41 import javax.net.ssl.SSLContext;
42 import javax.net.ssl.SSLSocket;
43 import javax.net.ssl.SSLSocketFactory;
44 import okio.BufferedSink;
45 import okio.BufferedSource;
46 
47 /**
48  * Configures and creates HTTP connections. Most applications can use a single
49  * OkHttpClient for all of their HTTP requests - benefiting from a shared
50  * response cache, thread pool, connection re-use, etc.
51  *
52  * <p>Instances of OkHttpClient are intended to be fully configured before they're
53  * shared - once shared they should be treated as immutable and can safely be used
54  * to concurrently open new connections. If required, threads can call
55  * {@link #clone()} to make a shallow copy of the OkHttpClient that can be
56  * safely modified with further configuration changes.
57  */
58 public class OkHttpClient implements Cloneable {
59   private static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
60       Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_1_1);
61 
62   private static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
63       ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT);
64 
65   static {
66     Internal.instance = new Internal() {
67       @Override public Transport newTransport(
68           Connection connection, HttpEngine httpEngine) throws IOException {
69         return connection.newTransport(httpEngine);
70       }
71 
72       @Override public boolean clearOwner(Connection connection) {
73         return connection.clearOwner();
74       }
75 
76       @Override public void closeIfOwnedBy(Connection connection, Object owner) throws IOException {
77         connection.closeIfOwnedBy(owner);
78       }
79 
80       @Override public int recycleCount(Connection connection) {
81         return connection.recycleCount();
82       }
83 
84       @Override public void setProtocol(Connection connection, Protocol protocol) {
85         connection.setProtocol(protocol);
86       }
87 
88       @Override public void setOwner(Connection connection, HttpEngine httpEngine) {
89         connection.setOwner(httpEngine);
90       }
91 
92       @Override public boolean isReadable(Connection pooled) {
93         return pooled.isReadable();
94       }
95 
96       @Override public void addLenient(Headers.Builder builder, String line) {
97         builder.addLenient(line);
98       }
99 
100       @Override public void addLenient(Headers.Builder builder, String name, String value) {
101         builder.addLenient(name, value);
102       }
103 
104       @Override public void setCache(OkHttpClient client, InternalCache internalCache) {
105         client.setInternalCache(internalCache);
106       }
107 
108       @Override public InternalCache internalCache(OkHttpClient client) {
109         return client.internalCache();
110       }
111 
112       @Override public void recycle(ConnectionPool pool, Connection connection) {
113         pool.recycle(connection);
114       }
115 
116       @Override public RouteDatabase routeDatabase(OkHttpClient client) {
117         return client.routeDatabase();
118       }
119 
120       @Override public Network network(OkHttpClient client) {
121         return client.network;
122       }
123 
124       @Override public void setNetwork(OkHttpClient client, Network network) {
125         client.network = network;
126       }
127 
128       @Override public void connectAndSetOwner(OkHttpClient client, Connection connection,
129           HttpEngine owner, Request request) throws RouteException {
130         connection.connectAndSetOwner(client, owner, request);
131       }
132 
133       @Override
134       public void callEnqueue(Call call, Callback responseCallback, boolean forWebSocket) {
135         call.enqueue(responseCallback, forWebSocket);
136       }
137 
138       @Override public void callEngineReleaseConnection(Call call) throws IOException {
139         call.engine.releaseConnection();
140       }
141 
142       @Override public Connection callEngineGetConnection(Call call) {
143         return call.engine.getConnection();
144       }
145 
146       @Override public BufferedSource connectionRawSource(Connection connection) {
147         return connection.rawSource();
148       }
149 
150       @Override public BufferedSink connectionRawSink(Connection connection) {
151         return connection.rawSink();
152       }
153 
154       @Override public void connectionSetOwner(Connection connection, Object owner) {
155         connection.setOwner(owner);
156       }
157 
158       @Override
159       public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
160         tlsConfiguration.apply(sslSocket, isFallback);
161       }
162 
163       @Override public HttpUrl getHttpUrlChecked(String url)
164           throws MalformedURLException, UnknownHostException {
165         return HttpUrl.getChecked(url);
166       }
167     };
168   }
169 
170   /** Lazily-initialized. */
171   private static SSLSocketFactory defaultSslSocketFactory;
172 
173   private final RouteDatabase routeDatabase;
174   private Dispatcher dispatcher;
175   private Proxy proxy;
176   private List<Protocol> protocols;
177   private List<ConnectionSpec> connectionSpecs;
178   private final List<Interceptor> interceptors = new ArrayList<>();
179   private final List<Interceptor> networkInterceptors = new ArrayList<>();
180   private ProxySelector proxySelector;
181   private CookieHandler cookieHandler;
182 
183   /** Non-null if this client is caching; possibly by {@code cache}. */
184   private InternalCache internalCache;
185   private Cache cache;
186 
187   private SocketFactory socketFactory;
188   private SSLSocketFactory sslSocketFactory;
189   private HostnameVerifier hostnameVerifier;
190   private CertificatePinner certificatePinner;
191   private Authenticator authenticator;
192   private ConnectionPool connectionPool;
193   private Network network;
194   private boolean followSslRedirects = true;
195   private boolean followRedirects = true;
196   private boolean retryOnConnectionFailure = true;
197   private int connectTimeout = 10_000;
198   private int readTimeout = 10_000;
199   private int writeTimeout = 10_000;
200 
OkHttpClient()201   public OkHttpClient() {
202     routeDatabase = new RouteDatabase();
203     dispatcher = new Dispatcher();
204   }
205 
OkHttpClient(OkHttpClient okHttpClient)206   private OkHttpClient(OkHttpClient okHttpClient) {
207     this.routeDatabase = okHttpClient.routeDatabase;
208     this.dispatcher = okHttpClient.dispatcher;
209     this.proxy = okHttpClient.proxy;
210     this.protocols = okHttpClient.protocols;
211     this.connectionSpecs = okHttpClient.connectionSpecs;
212     this.interceptors.addAll(okHttpClient.interceptors);
213     this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
214     this.proxySelector = okHttpClient.proxySelector;
215     this.cookieHandler = okHttpClient.cookieHandler;
216     this.cache = okHttpClient.cache;
217     this.internalCache = cache != null ? cache.internalCache : okHttpClient.internalCache;
218     this.socketFactory = okHttpClient.socketFactory;
219     this.sslSocketFactory = okHttpClient.sslSocketFactory;
220     this.hostnameVerifier = okHttpClient.hostnameVerifier;
221     this.certificatePinner = okHttpClient.certificatePinner;
222     this.authenticator = okHttpClient.authenticator;
223     this.connectionPool = okHttpClient.connectionPool;
224     this.network = okHttpClient.network;
225     this.followSslRedirects = okHttpClient.followSslRedirects;
226     this.followRedirects = okHttpClient.followRedirects;
227     this.retryOnConnectionFailure = okHttpClient.retryOnConnectionFailure;
228     this.connectTimeout = okHttpClient.connectTimeout;
229     this.readTimeout = okHttpClient.readTimeout;
230     this.writeTimeout = okHttpClient.writeTimeout;
231   }
232 
233   /**
234    * Sets the default connect timeout for new connections. A value of 0 means no timeout, otherwise
235    * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
236    *
237    * @see URLConnection#setConnectTimeout(int)
238    */
setConnectTimeout(long timeout, TimeUnit unit)239   public void setConnectTimeout(long timeout, TimeUnit unit) {
240     if (timeout < 0) throw new IllegalArgumentException("timeout < 0");
241     if (unit == null) throw new IllegalArgumentException("unit == null");
242     long millis = unit.toMillis(timeout);
243     if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException("Timeout too large.");
244     if (millis == 0 && timeout > 0) throw new IllegalArgumentException("Timeout too small.");
245     connectTimeout = (int) millis;
246   }
247 
248   /** Default connect timeout (in milliseconds). */
getConnectTimeout()249   public int getConnectTimeout() {
250     return connectTimeout;
251   }
252 
253   /**
254    * Sets the default read timeout for new connections. A value of 0 means no timeout, otherwise
255    * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
256    *
257    * @see URLConnection#setReadTimeout(int)
258    */
setReadTimeout(long timeout, TimeUnit unit)259   public void setReadTimeout(long timeout, TimeUnit unit) {
260     if (timeout < 0) throw new IllegalArgumentException("timeout < 0");
261     if (unit == null) throw new IllegalArgumentException("unit == null");
262     long millis = unit.toMillis(timeout);
263     if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException("Timeout too large.");
264     if (millis == 0 && timeout > 0) throw new IllegalArgumentException("Timeout too small.");
265     readTimeout = (int) millis;
266   }
267 
268   /** Default read timeout (in milliseconds). */
getReadTimeout()269   public int getReadTimeout() {
270     return readTimeout;
271   }
272 
273   /**
274    * Sets the default write timeout for new connections. A value of 0 means no timeout, otherwise
275    * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
276    */
setWriteTimeout(long timeout, TimeUnit unit)277   public void setWriteTimeout(long timeout, TimeUnit unit) {
278     if (timeout < 0) throw new IllegalArgumentException("timeout < 0");
279     if (unit == null) throw new IllegalArgumentException("unit == null");
280     long millis = unit.toMillis(timeout);
281     if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException("Timeout too large.");
282     if (millis == 0 && timeout > 0) throw new IllegalArgumentException("Timeout too small.");
283     writeTimeout = (int) millis;
284   }
285 
286   /** Default write timeout (in milliseconds). */
getWriteTimeout()287   public int getWriteTimeout() {
288     return writeTimeout;
289   }
290 
291   /**
292    * Sets the HTTP proxy that will be used by connections created by this
293    * client. This takes precedence over {@link #setProxySelector}, which is
294    * only honored when this proxy is null (which it is by default). To disable
295    * proxy use completely, call {@code setProxy(Proxy.NO_PROXY)}.
296    */
setProxy(Proxy proxy)297   public OkHttpClient setProxy(Proxy proxy) {
298     this.proxy = proxy;
299     return this;
300   }
301 
getProxy()302   public Proxy getProxy() {
303     return proxy;
304   }
305 
306   /**
307    * Sets the proxy selection policy to be used if no {@link #setProxy proxy}
308    * is specified explicitly. The proxy selector may return multiple proxies;
309    * in that case they will be tried in sequence until a successful connection
310    * is established.
311    *
312    * <p>If unset, the {@link ProxySelector#getDefault() system-wide default}
313    * proxy selector will be used.
314    */
setProxySelector(ProxySelector proxySelector)315   public OkHttpClient setProxySelector(ProxySelector proxySelector) {
316     this.proxySelector = proxySelector;
317     return this;
318   }
319 
getProxySelector()320   public ProxySelector getProxySelector() {
321     return proxySelector;
322   }
323 
324   /**
325    * Sets the cookie handler to be used to read outgoing cookies and write
326    * incoming cookies.
327    *
328    * <p>If unset, the {@link CookieHandler#getDefault() system-wide default}
329    * cookie handler will be used.
330    */
setCookieHandler(CookieHandler cookieHandler)331   public OkHttpClient setCookieHandler(CookieHandler cookieHandler) {
332     this.cookieHandler = cookieHandler;
333     return this;
334   }
335 
getCookieHandler()336   public CookieHandler getCookieHandler() {
337     return cookieHandler;
338   }
339 
340   /** Sets the response cache to be used to read and write cached responses. */
setInternalCache(InternalCache internalCache)341   void setInternalCache(InternalCache internalCache) {
342     this.internalCache = internalCache;
343     this.cache = null;
344   }
345 
internalCache()346   InternalCache internalCache() {
347     return internalCache;
348   }
349 
setCache(Cache cache)350   public OkHttpClient setCache(Cache cache) {
351     this.cache = cache;
352     this.internalCache = null;
353     return this;
354   }
355 
getCache()356   public Cache getCache() {
357     return cache;
358   }
359 
360   /**
361    * Sets the socket factory used to create connections. OkHttp only uses
362    * the parameterless {@link SocketFactory#createSocket() createSocket()}
363    * method to create unconnected sockets. Overriding this method,
364    * e. g., allows the socket to be bound to a specific local address.
365    *
366    * <p>If unset, the {@link SocketFactory#getDefault() system-wide default}
367    * socket factory will be used.
368    */
setSocketFactory(SocketFactory socketFactory)369   public OkHttpClient setSocketFactory(SocketFactory socketFactory) {
370     this.socketFactory = socketFactory;
371     return this;
372   }
373 
getSocketFactory()374   public SocketFactory getSocketFactory() {
375     return socketFactory;
376   }
377 
378   /**
379    * Sets the socket factory used to secure HTTPS connections.
380    *
381    * <p>If unset, a lazily created SSL socket factory will be used.
382    */
setSslSocketFactory(SSLSocketFactory sslSocketFactory)383   public OkHttpClient setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
384     this.sslSocketFactory = sslSocketFactory;
385     return this;
386   }
387 
getSslSocketFactory()388   public SSLSocketFactory getSslSocketFactory() {
389     return sslSocketFactory;
390   }
391 
392   /**
393    * Sets the verifier used to confirm that response certificates apply to
394    * requested hostnames for HTTPS connections.
395    *
396    * <p>If unset, a default hostname verifier will be used.
397    */
setHostnameVerifier(HostnameVerifier hostnameVerifier)398   public OkHttpClient setHostnameVerifier(HostnameVerifier hostnameVerifier) {
399     this.hostnameVerifier = hostnameVerifier;
400     return this;
401   }
402 
getHostnameVerifier()403   public HostnameVerifier getHostnameVerifier() {
404     return hostnameVerifier;
405   }
406 
407   /**
408    * Sets the certificate pinner that constrains which certificates are trusted.
409    * By default HTTPS connections rely on only the {@link #setSslSocketFactory
410    * SSL socket factory} to establish trust. Pinning certificates avoids the
411    * need to trust certificate authorities.
412    */
setCertificatePinner(CertificatePinner certificatePinner)413   public OkHttpClient setCertificatePinner(CertificatePinner certificatePinner) {
414     this.certificatePinner = certificatePinner;
415     return this;
416   }
417 
getCertificatePinner()418   public CertificatePinner getCertificatePinner() {
419     return certificatePinner;
420   }
421 
422   /**
423    * Sets the authenticator used to respond to challenges from the remote web
424    * server or proxy server.
425    *
426    * <p>If unset, the {@link java.net.Authenticator#setDefault system-wide default}
427    * authenticator will be used.
428    */
setAuthenticator(Authenticator authenticator)429   public OkHttpClient setAuthenticator(Authenticator authenticator) {
430     this.authenticator = authenticator;
431     return this;
432   }
433 
getAuthenticator()434   public Authenticator getAuthenticator() {
435     return authenticator;
436   }
437 
438   /**
439    * Sets the connection pool used to recycle HTTP and HTTPS connections.
440    *
441    * <p>If unset, the {@link ConnectionPool#getDefault() system-wide
442    * default} connection pool will be used.
443    */
setConnectionPool(ConnectionPool connectionPool)444   public OkHttpClient setConnectionPool(ConnectionPool connectionPool) {
445     this.connectionPool = connectionPool;
446     return this;
447   }
448 
getConnectionPool()449   public ConnectionPool getConnectionPool() {
450     return connectionPool;
451   }
452 
453   /**
454    * Configure this client to follow redirects from HTTPS to HTTP and from HTTP
455    * to HTTPS.
456    *
457    * <p>If unset, protocol redirects will be followed. This is different than
458    * the built-in {@code HttpURLConnection}'s default.
459    */
setFollowSslRedirects(boolean followProtocolRedirects)460   public OkHttpClient setFollowSslRedirects(boolean followProtocolRedirects) {
461     this.followSslRedirects = followProtocolRedirects;
462     return this;
463   }
464 
getFollowSslRedirects()465   public boolean getFollowSslRedirects() {
466     return followSslRedirects;
467   }
468 
469   /** Configure this client to follow redirects. If unset, redirects be followed. */
setFollowRedirects(boolean followRedirects)470   public void setFollowRedirects(boolean followRedirects) {
471     this.followRedirects = followRedirects;
472   }
473 
getFollowRedirects()474   public boolean getFollowRedirects() {
475     return followRedirects;
476   }
477 
478   /**
479    * Configure this client to retry or not when a connectivity problem is encountered. By default,
480    * this client silently recovers from the following problems:
481    *
482    * <ul>
483    *   <li><strong>Unreachable IP addresses.</strong> If the URL's host has multiple IP addresses,
484    *       failure to reach any individual IP address doesn't fail the overall request. This can
485    *       increase availability of multi-homed services.
486    *   <li><strong>Stale pooled connections.</strong> The {@link ConnectionPool} reuses sockets
487    *       to decrease request latency, but these connections will occasionally time out.
488    *   <li><strong>Unreachable proxy servers.</strong> A {@link ProxySelector} can be used to
489    *       attempt multiple proxy servers in sequence, eventually falling back to a direct
490    *       connection.
491    * </ul>
492    *
493    * Set this to false to avoid retrying requests when doing so is destructive. In this case the
494    * calling application should do its own recovery of connectivity failures.
495    */
setRetryOnConnectionFailure(boolean retryOnConnectionFailure)496   public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
497     this.retryOnConnectionFailure = retryOnConnectionFailure;
498   }
499 
getRetryOnConnectionFailure()500   public boolean getRetryOnConnectionFailure() {
501     return retryOnConnectionFailure;
502   }
503 
routeDatabase()504   RouteDatabase routeDatabase() {
505     return routeDatabase;
506   }
507 
508   /**
509    * Sets the dispatcher used to set policy and execute asynchronous requests.
510    * Must not be null.
511    */
setDispatcher(Dispatcher dispatcher)512   public OkHttpClient setDispatcher(Dispatcher dispatcher) {
513     if (dispatcher == null) throw new IllegalArgumentException("dispatcher == null");
514     this.dispatcher = dispatcher;
515     return this;
516   }
517 
getDispatcher()518   public Dispatcher getDispatcher() {
519     return dispatcher;
520   }
521 
522   /**
523    * Configure the protocols used by this client to communicate with remote
524    * servers. By default this client will prefer the most efficient transport
525    * available, falling back to more ubiquitous protocols. Applications should
526    * only call this method to avoid specific compatibility problems, such as web
527    * servers that behave incorrectly when SPDY is enabled.
528    *
529    * <p>The following protocols are currently supported:
530    * <ul>
531    *   <li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">http/1.1</a>
532    *   <li><a href="http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1">spdy/3.1</a>
533    *   <li><a href="http://tools.ietf.org/html/draft-ietf-httpbis-http2-17">h2</a>
534    * </ul>
535    *
536    * <p><strong>This is an evolving set.</strong> Future releases include
537    * support for transitional protocols. The http/1.1 transport will never be
538    * dropped.
539    *
540    * <p>If multiple protocols are specified, <a
541    * href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg">ALPN</a>
542    * will be used to negotiate a transport.
543    *
544    * <p>{@link Protocol#HTTP_1_0} is not supported in this set. Requests are
545    * initiated with {@code HTTP/1.1} only. If the server responds with {@code
546    * HTTP/1.0}, that will be exposed by {@link Response#protocol()}.
547    *
548    * @param protocols the protocols to use, in order of preference. The list
549    *     must contain {@link Protocol#HTTP_1_1}. It must not contain null or
550    *     {@link Protocol#HTTP_1_0}.
551    */
setProtocols(List<Protocol> protocols)552   public OkHttpClient setProtocols(List<Protocol> protocols) {
553     protocols = Util.immutableList(protocols);
554     if (!protocols.contains(Protocol.HTTP_1_1)) {
555       throw new IllegalArgumentException("protocols doesn't contain http/1.1: " + protocols);
556     }
557     if (protocols.contains(Protocol.HTTP_1_0)) {
558       throw new IllegalArgumentException("protocols must not contain http/1.0: " + protocols);
559     }
560     if (protocols.contains(null)) {
561       throw new IllegalArgumentException("protocols must not contain null");
562     }
563     this.protocols = Util.immutableList(protocols);
564     return this;
565   }
566 
getProtocols()567   public List<Protocol> getProtocols() {
568     return protocols;
569   }
570 
setConnectionSpecs(List<ConnectionSpec> connectionSpecs)571   public OkHttpClient setConnectionSpecs(List<ConnectionSpec> connectionSpecs) {
572     this.connectionSpecs = Util.immutableList(connectionSpecs);
573     return this;
574   }
575 
getConnectionSpecs()576   public List<ConnectionSpec> getConnectionSpecs() {
577     return connectionSpecs;
578   }
579 
580   /**
581    * Returns a modifiable list of interceptors that observe the full span of each call: from before
582    * the connection is established (if any) until after the response source is selected (either the
583    * origin server, cache, or both).
584    */
interceptors()585   public List<Interceptor> interceptors() {
586     return interceptors;
587   }
588 
589   /**
590    * Returns a modifiable list of interceptors that observe a single network request and response.
591    * These interceptors must call {@link Interceptor.Chain#proceed} exactly once: it is an error for
592    * a network interceptor to short-circuit or repeat a network request.
593    */
networkInterceptors()594   public List<Interceptor> networkInterceptors() {
595     return networkInterceptors;
596   }
597 
598   /**
599    * Prepares the {@code request} to be executed at some point in the future.
600    */
newCall(Request request)601   public Call newCall(Request request) {
602     return new Call(this, request);
603   }
604 
605   /**
606    * Cancels all scheduled or in-flight calls tagged with {@code tag}. Requests
607    * that are already complete cannot be canceled.
608    */
cancel(Object tag)609   public OkHttpClient cancel(Object tag) {
610     getDispatcher().cancel(tag);
611     return this;
612   }
613 
614   /**
615    * Returns a shallow copy of this OkHttpClient that uses the system-wide
616    * default for each field that hasn't been explicitly configured.
617    */
copyWithDefaults()618   OkHttpClient copyWithDefaults() {
619     OkHttpClient result = new OkHttpClient(this);
620     if (result.proxySelector == null) {
621       result.proxySelector = ProxySelector.getDefault();
622     }
623     if (result.cookieHandler == null) {
624       result.cookieHandler = CookieHandler.getDefault();
625     }
626     if (result.socketFactory == null) {
627       result.socketFactory = SocketFactory.getDefault();
628     }
629     if (result.sslSocketFactory == null) {
630       result.sslSocketFactory = getDefaultSSLSocketFactory();
631     }
632     if (result.hostnameVerifier == null) {
633       result.hostnameVerifier = OkHostnameVerifier.INSTANCE;
634     }
635     if (result.certificatePinner == null) {
636       result.certificatePinner = CertificatePinner.DEFAULT;
637     }
638     if (result.authenticator == null) {
639       result.authenticator = AuthenticatorAdapter.INSTANCE;
640     }
641     if (result.connectionPool == null) {
642       result.connectionPool = ConnectionPool.getDefault();
643     }
644     if (result.protocols == null) {
645       result.protocols = DEFAULT_PROTOCOLS;
646     }
647     if (result.connectionSpecs == null) {
648       result.connectionSpecs = DEFAULT_CONNECTION_SPECS;
649     }
650     if (result.network == null) {
651       result.network = Network.DEFAULT;
652     }
653     return result;
654   }
655 
656   /**
657    * Java and Android programs default to using a single global SSL context,
658    * accessible to HTTP clients as {@link SSLSocketFactory#getDefault()}. If we
659    * used the shared SSL context, when OkHttp enables ALPN for its SPDY-related
660    * stuff, it would also enable ALPN for other usages, which might crash them
661    * because ALPN is enabled when it isn't expected to be.
662    *
663    * <p>This code avoids that by defaulting to an OkHttp-created SSL context.
664    * The drawback of this approach is that apps that customize the global SSL
665    * context will lose these customizations.
666    */
getDefaultSSLSocketFactory()667   private synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
668     if (defaultSslSocketFactory == null) {
669       try {
670         SSLContext sslContext = SSLContext.getInstance("TLS");
671         sslContext.init(null, null, null);
672         defaultSslSocketFactory = sslContext.getSocketFactory();
673       } catch (GeneralSecurityException e) {
674         throw new AssertionError(); // The system has no TLS. Just give up.
675       }
676     }
677     return defaultSslSocketFactory;
678   }
679 
680   /** Returns a shallow copy of this OkHttpClient. */
clone()681   @Override public OkHttpClient clone() {
682     return new OkHttpClient(this);
683   }
684 }
685