Skip to content

Commit

Permalink
Fix opening too many TCP connections when issuing a high number of re…
Browse files Browse the repository at this point in the history
…quests (#646)

Resolution was to use a static reference to the SSL Socket Factory, rather than getting it each time from the SSLContext.
  • Loading branch information
pmatte1 authored and Matt Willer committed Sep 13, 2018
1 parent 167c61f commit 2ed8047
Showing 1 changed file with 50 additions and 43 deletions.
93 changes: 50 additions & 43 deletions src/main/java/com/box/sdk/BoxAPIRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;

import com.box.sdk.http.HttpHeaders;
import com.box.sdk.http.HttpMethod;
Expand All @@ -43,6 +44,7 @@ public class BoxAPIRequest {
private static final Logger LOGGER = Logger.getLogger(BoxAPIRequest.class.getName());
private static final int BUFFER_SIZE = 8192;
private static final int MAX_REDIRECTS = 3;
private static SSLSocketFactory sslSocketFactory;

private final BoxAPIConnection api;
private final List<RequestHeader> headers;
Expand All @@ -58,7 +60,52 @@ public class BoxAPIRequest {
private int numRedirects;
private boolean followRedirects = true;
private boolean shouldAuthenticate;
private SSLContext sslContext;

static {
// Setup the SSL context manually to force newer TLS version on legacy Java environments
// This is necessary because Java 7 uses TLSv1.0 by default, but the Box API will need
// to deprecate this protocol in the future. To prevent clients from breaking, we must
// ensure that they are using TLSv1.1 or greater!
SSLContext sc = null;
try {
sc = SSLContext.getDefault();
SSLParameters params = sc.getDefaultSSLParameters();
boolean supportsNewTLS = false;
for (String protocol : params.getProtocols()) {
if (protocol.compareTo("TLSv1") > 0) {
supportsNewTLS = true;
break;
}
}
if (!supportsNewTLS) {
// Try to upgrade to a higher TLS version
sc = null;
sc = SSLContext.getInstance("TLSv1.1");
sc.init(null, null, new java.security.SecureRandom());
sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, new java.security.SecureRandom());
}
} catch (NoSuchAlgorithmException ex) {
if (sc == null) {
LOGGER.warning("Unable to set up SSL context for HTTPS! This may result in the inability "
+ " to connect to the Box API.");
}
if (sc != null && sc.getProtocol().equals("TLSv1")) {
// Could not find a good version of TLS
LOGGER.warning("Using deprecated TLSv1 protocol, which will be deprecated by the Box API! Upgrade "
+ "to a newer version of Java as soon as possible.");
}
} catch (KeyManagementException ex) {
LOGGER.warning("Exception when initializing SSL Context! This may result in the inabilty to connect to "
+ "the Box API");
sc = null;
}

if (sc != null) {
sslSocketFactory = sc.getSocketFactory();
}

}

/**
* Constructs an unauthenticated BoxAPIRequest.
Expand Down Expand Up @@ -97,46 +144,6 @@ public BoxAPIRequest(BoxAPIConnection api, URL url, String method) {
this.addHeader("Accept-Encoding", "gzip");
this.addHeader("Accept-Charset", "utf-8");

// Setup the SSL context manually to force newer TLS version on legacy Java environments
// This is necessary because Java 7 uses TLSv1.0 by default, but the Box API will need
// to deprecate this protocol in the future. To prevent clients from breaking, we must
// ensure that they are using TLSv1.1 or greater!
SSLContext sc = null;
try {
sc = SSLContext.getDefault();
SSLParameters params = sc.getDefaultSSLParameters();
boolean supportsNewTLS = false;
for (String protocol : params.getProtocols()) {
if (protocol.compareTo("TLSv1") > 0) {
supportsNewTLS = true;
break;
}
}
if (!supportsNewTLS) {
// Try to upgrade to a higher TLS version
sc = null;
sc = SSLContext.getInstance("TLSv1.1");
sc.init(null, null, new java.security.SecureRandom());
sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, new java.security.SecureRandom());
}
} catch (NoSuchAlgorithmException ex) {
if (sc == null) {
LOGGER.warning("Unable to set up SSL context for HTTPS! This may result in the inability "
+ " to connect to the Box API.");
}
if (sc != null && sc.getProtocol().equals("TLSv1")) {
// Could not find a good version of TLS
LOGGER.warning("Using deprecated TLSv1 protocol, which will be deprecated by the Box API! Upgrade "
+ "to a newer version of Java as soon as possible.");
}
} catch (KeyManagementException ex) {

LOGGER.warning("Exception when initializing SSL Context! This may result in the inabilty to connect to "
+ "the Box API");
sc = null;
}
this.sslContext = sc;
}

/**
Expand Down Expand Up @@ -475,8 +482,8 @@ private BoxAPIResponse trySend(ProgressListener listener) {
if (connection instanceof HttpsURLConnection) {
HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;

if (this.sslContext != null) {
httpsConnection.setSSLSocketFactory(this.sslContext.getSocketFactory());
if (sslSocketFactory != null) {
httpsConnection.setSSLSocketFactory(sslSocketFactory);
}
}

Expand Down

0 comments on commit 2ed8047

Please sign in to comment.