mirror of
https://github.com/square/okhttp.git
synced 2026-01-27 04:22:07 +03:00
Fix a severe bug where multiple TLS tunnels were attempted.
The previous code would attempt a TLS tunnel on reused HTTPS connections, even after the tunnel had been established. This is a severe protocol error!
This commit is contained in:
@@ -449,25 +449,21 @@ public final class HttpsURLConnectionImpl extends OkHttpsConnection {
|
||||
* an SSL3 only fallback mode without compression.
|
||||
*/
|
||||
private void makeSslConnection(boolean tlsTolerant) throws IOException {
|
||||
// make an SSL Tunnel on the first message pair of each SSL + proxy connection
|
||||
// Get a connection. This may return a pooled connection!
|
||||
if (connection == null) {
|
||||
connection = openSocketConnection();
|
||||
if (connection.getAddress().requiresTunnel()) {
|
||||
makeTunnel(policy, connection, getRequestHeaders());
|
||||
}
|
||||
}
|
||||
|
||||
// if super.makeConnection returned a connection from the
|
||||
// pool, sslSocket needs to be initialized here. If it is
|
||||
// a new connection, it will be initialized by
|
||||
// getSecureSocket below.
|
||||
sslSocket = connection.getSecureSocketIfConnected();
|
||||
|
||||
// we already have an SSL connection,
|
||||
// If the TLS connection is ready, use it.
|
||||
if (sslSocket != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The TLS connection isn't ready. Build a tunnel if necessary and then handshake.
|
||||
if (connection.getAddress().requiresTunnel()) {
|
||||
makeTunnel(policy, connection, getRequestHeaders());
|
||||
}
|
||||
sslSocket = connection.setupSecureSocket(
|
||||
enclosing.getSSLSocketFactory(), enclosing.getHostnameVerifier(), tlsTolerant);
|
||||
}
|
||||
|
||||
@@ -809,6 +809,32 @@ public final class URLConnectionTest extends TestCase {
|
||||
assertContent("this response comes via a proxy", connection);
|
||||
}
|
||||
|
||||
public void testProxyWithConnectionReuse() throws IOException {
|
||||
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
|
||||
RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
|
||||
|
||||
server.useHttps(socketFactory, true);
|
||||
server.enqueue(new MockResponse()
|
||||
.setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
|
||||
.clearHeaders());
|
||||
server.enqueue(new MockResponse().setBody("response 1"));
|
||||
server.enqueue(new MockResponse().setBody("response 2"));
|
||||
server.play();
|
||||
|
||||
URL url = new URL("https://android.com/foo");
|
||||
OkHttpsConnection connection1 = (OkHttpsConnection) openConnection(
|
||||
url, server.toProxyAddress());
|
||||
connection1.setSSLSocketFactory(socketFactory);
|
||||
connection1.setHostnameVerifier(hostnameVerifier);
|
||||
assertContent("response 1", connection1);
|
||||
|
||||
OkHttpsConnection connection2 = (OkHttpsConnection) openConnection(
|
||||
url, server.toProxyAddress());
|
||||
connection2.setSSLSocketFactory(socketFactory);
|
||||
connection2.setHostnameVerifier(hostnameVerifier);
|
||||
assertContent("response 2", connection2);
|
||||
}
|
||||
|
||||
public void testDisconnectedConnection() throws IOException {
|
||||
server.enqueue(new MockResponse().setBody("ABCDEFGHIJKLMNOPQR"));
|
||||
server.play();
|
||||
|
||||
Reference in New Issue
Block a user