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