Skip to content

Commit

Permalink
fix #184: OkHttp no longer uses default ssl context.
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrian Cole committed Feb 9, 2014
1 parent de6d505 commit 5d7fdba
Showing 1 changed file with 31 additions and 6 deletions.
37 changes: 31 additions & 6 deletions okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/
package com.squareup.okhttp;

import com.squareup.okhttp.internal.bytes.ByteString;
import com.squareup.okhttp.internal.Util;
import com.squareup.okhttp.internal.bytes.ByteString;
import com.squareup.okhttp.internal.http.HttpAuthenticator;
import com.squareup.okhttp.internal.http.HttpURLConnectionImpl;
import com.squareup.okhttp.internal.http.HttpsURLConnectionImpl;
Expand All @@ -31,11 +31,12 @@
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;

/** Configures and creates HTTP connections. */
Expand Down Expand Up @@ -202,8 +203,7 @@ public OkResponseCache getOkResponseCache() {
/**
* Sets the socket factory used to secure HTTPS connections.
*
* <p>If unset, the {@link HttpsURLConnection#getDefaultSSLSocketFactory()
* system-wide default} SSL socket factory will be used.
* <p>If unset, a lazily created SSL socket factory will be used.
*/
public OkHttpClient setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
Expand All @@ -218,7 +218,8 @@ public SSLSocketFactory getSslSocketFactory() {
* Sets the verifier used to confirm that response certificates apply to
* requested hostnames for HTTPS connections.
*
* <p>If unset, the {@link HttpsURLConnection#getDefaultHostnameVerifier()
* <p>If unset, the
* {@link javax.net.ssl.HttpsURLConnection#getDefaultHostnameVerifier()
* system-wide default} hostname verifier will be used.
*/
public OkHttpClient setHostnameVerifier(HostnameVerifier hostnameVerifier) {
Expand Down Expand Up @@ -422,7 +423,7 @@ OkHttpClient copyWithDefaults() {
result.responseCache = toOkResponseCacheOrNull(ResponseCache.getDefault());
}
if (result.sslSocketFactory == null) {
result.sslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
result.sslSocketFactory = getDefaultSSLSocketFactory();
}
if (result.hostnameVerifier == null) {
result.hostnameVerifier = OkHostnameVerifier.INSTANCE;
Expand All @@ -439,6 +440,30 @@ OkHttpClient copyWithDefaults() {
return result;
}

/**
* Java and Android programs default to using a single global SSL context,
* accessible to HTTP clients as {@link SSLSocketFactory#getDefault()}. If we
* used the shared SSL context, when OkHttp enables NPN for its SPDY-related
* stuff, it would also enable NPN for other usages, which might crash them
* because NPN is enabled when it isn't expected to be.
* <p>
* This code avoids that by defaulting to an OkHttp created SSL context. The
* significant drawback of this approach is that apps that customize the
* global SSL context will lose these customizations.
*/
private synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
if (sslSocketFactory == null) {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new AssertionError(); // The system has no TLS. Just give up.
}
}
return sslSocketFactory;
}

/** Returns a shallow copy of this OkHttpClient. */
@Override public OkHttpClient clone() {
try {
Expand Down

0 comments on commit 5d7fdba

Please sign in to comment.