Merge "Don't reuse an SSL socket if the socket factory has changed."
diff --git a/luni/src/main/java/libcore/net/http/HttpConnection.java b/luni/src/main/java/libcore/net/http/HttpConnection.java
index 779f80f..66dec4d 100644
--- a/luni/src/main/java/libcore/net/http/HttpConnection.java
+++ b/luni/src/main/java/libcore/net/http/HttpConnection.java
@@ -86,15 +86,15 @@
this.socket = socketCandidate;
}
- public static HttpConnection connect(URI uri, Proxy proxy, boolean requiresTunnel,
- int connectTimeout) throws IOException {
+ public static HttpConnection connect(URI uri, SSLSocketFactory sslSocketFactory,
+ Proxy proxy, boolean requiresTunnel, int connectTimeout) throws IOException {
/*
* Try an explicitly-specified proxy.
*/
if (proxy != null) {
Address address = (proxy.type() == Proxy.Type.DIRECT)
- ? new Address(uri)
- : new Address(uri, proxy, requiresTunnel);
+ ? new Address(uri, sslSocketFactory)
+ : new Address(uri, sslSocketFactory, proxy, requiresTunnel);
return HttpConnectionPool.INSTANCE.get(address, connectTimeout);
}
@@ -112,7 +112,8 @@
continue;
}
try {
- Address address = new Address(uri, selectedProxy, requiresTunnel);
+ Address address = new Address(uri, sslSocketFactory,
+ selectedProxy, requiresTunnel);
return HttpConnectionPool.INSTANCE.get(address, connectTimeout);
} catch (IOException e) {
// failed to connect, tell it to the selector
@@ -124,7 +125,7 @@
/*
* Try a direct connection. If this fails, this method will throw.
*/
- return HttpConnectionPool.INSTANCE.get(new Address(uri), connectTimeout);
+ return HttpConnectionPool.INSTANCE.get(new Address(uri, sslSocketFactory), connectTimeout);
}
public void closeSocketAndStreams() {
@@ -258,7 +259,8 @@
/**
* This address has two parts: the address we connect to directly and the
* origin address of the resource. These are the same unless a proxy is
- * being used.
+ * being used. It also includes the SSL socket factory so that a socket will
+ * not be reused if its SSL configuration is different.
*/
public static final class Address {
private final Proxy proxy;
@@ -267,12 +269,14 @@
private final int uriPort;
private final String socketHost;
private final int socketPort;
+ private final SSLSocketFactory sslSocketFactory;
- public Address(URI uri) throws UnknownHostException {
+ public Address(URI uri, SSLSocketFactory sslSocketFactory) throws UnknownHostException {
this.proxy = null;
this.requiresTunnel = false;
this.uriHost = uri.getHost();
this.uriPort = uri.getEffectivePort();
+ this.sslSocketFactory = sslSocketFactory;
this.socketHost = uriHost;
this.socketPort = uriPort;
if (uriHost == null) {
@@ -286,11 +290,13 @@
* proxy. When doing so, we must avoid buffering bytes intended for
* the higher-level protocol.
*/
- public Address(URI uri, Proxy proxy, boolean requiresTunnel) throws UnknownHostException {
+ public Address(URI uri, SSLSocketFactory sslSocketFactory,
+ Proxy proxy, boolean requiresTunnel) throws UnknownHostException {
this.proxy = proxy;
this.requiresTunnel = requiresTunnel;
this.uriHost = uri.getHost();
this.uriPort = uri.getEffectivePort();
+ this.sslSocketFactory = sslSocketFactory;
SocketAddress proxyAddress = proxy.address();
if (!(proxyAddress instanceof InetSocketAddress)) {
@@ -315,6 +321,7 @@
return Objects.equal(this.proxy, that.proxy)
&& this.uriHost.equals(that.uriHost)
&& this.uriPort == that.uriPort
+ && Objects.equal(this.sslSocketFactory, that.sslSocketFactory)
&& this.requiresTunnel == that.requiresTunnel;
}
return false;
@@ -324,6 +331,7 @@
int result = 17;
result = 31 * result + uriHost.hashCode();
result = 31 * result + uriPort;
+ result = 31 * result + (sslSocketFactory != null ? sslSocketFactory.hashCode() : 0);
result = 31 * result + (proxy != null ? proxy.hashCode() : 0);
result = 31 * result + (requiresTunnel ? 1 : 0);
return result;
diff --git a/luni/src/main/java/libcore/net/http/HttpEngine.java b/luni/src/main/java/libcore/net/http/HttpEngine.java
index f32e553..820761a 100644
--- a/luni/src/main/java/libcore/net/http/HttpEngine.java
+++ b/luni/src/main/java/libcore/net/http/HttpEngine.java
@@ -38,6 +38,7 @@
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
+import javax.net.ssl.SSLSocketFactory;
import libcore.io.IoUtils;
import libcore.io.Streams;
import libcore.util.EmptyArray;
@@ -305,8 +306,8 @@
}
protected final HttpConnection openSocketConnection() throws IOException {
- HttpConnection result = HttpConnection.connect(
- uri, policy.getProxy(), requiresTunnel(), policy.getConnectTimeout());
+ HttpConnection result = HttpConnection.connect(uri, getSslSocketFactory(),
+ policy.getProxy(), requiresTunnel(), policy.getConnectTimeout());
Proxy proxy = result.getAddress().getProxy();
if (proxy != null) {
policy.setProxy(proxy);
@@ -731,6 +732,14 @@
return policy.usingProxy();
}
+ /**
+ * Returns the SSL configuration for connections created by this engine.
+ * We cannot reuse HTTPS connections if the socket factory has changed.
+ */
+ protected SSLSocketFactory getSslSocketFactory() {
+ return null;
+ }
+
protected final String getDefaultUserAgent() {
String agent = System.getProperty("http.agent");
return agent != null ? agent : ("Java" + System.getProperty("java.version"));
diff --git a/luni/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java b/luni/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java
index e213706..9e3e4ef 100644
--- a/luni/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java
+++ b/luni/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java
@@ -35,6 +35,7 @@
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
final class HttpsURLConnectionImpl extends HttpsURLConnection {
@@ -519,6 +520,10 @@
return false;
}
+ @Override protected SSLSocketFactory getSslSocketFactory() {
+ return enclosing.getSSLSocketFactory();
+ }
+
@Override protected HttpURLConnection getHttpConnectionToCache() {
return enclosing;
}
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index d16f14a..195b7b8 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -454,6 +454,7 @@
public void testConnectViaHttpsReusingConnections() throws IOException, InterruptedException {
TestSSLContext testSSLContext = TestSSLContext.create();
+ SSLSocketFactory clientSocketFactory = testSSLContext.clientContext.getSocketFactory();
server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
@@ -461,11 +462,11 @@
server.play();
HttpsURLConnection connection = (HttpsURLConnection) server.getUrl("/").openConnection();
- connection.setSSLSocketFactory(testSSLContext.clientContext.getSocketFactory());
+ connection.setSSLSocketFactory(clientSocketFactory);
assertContent("this response comes via HTTPS", connection);
connection = (HttpsURLConnection) server.getUrl("/").openConnection();
- connection.setSSLSocketFactory(testSSLContext.clientContext.getSocketFactory());
+ connection.setSSLSocketFactory(clientSocketFactory);
assertContent("another response via HTTPS", connection);
assertEquals(0, server.takeRequest().getSequenceNumber());