Index: net/socket/ssl_client_socket_unittest.cc |
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc |
index 2639870e81f36f4fefef5ad4626ced9bc629da13..c766b7c6178343c51cb9a7c796e8407b060cd065 100644 |
--- a/net/socket/ssl_client_socket_unittest.cc |
+++ b/net/socket/ssl_client_socket_unittest.cc |
@@ -599,9 +599,7 @@ class SSLClientSocketTest : public PlatformTest { |
} |
protected: |
- // Sets up a TCP connection to a HTTPS server. To actually do the SSL |
- // handshake, follow up with call to CreateAndConnectSSLClientSocket() below. |
- bool ConnectToTestServer(SpawnedTestServer::SSLOptions& ssl_options) { |
+ bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { |
test_server_.reset(new SpawnedTestServer( |
SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); |
if (!test_server_->Start()) { |
@@ -613,6 +611,14 @@ class SSLClientSocketTest : public PlatformTest { |
LOG(ERROR) << "Could not get SpawnedTestServer address list"; |
return false; |
} |
+ return true; |
+ } |
+ |
+ // Sets up a TCP connection to a HTTPS server. To actually do the SSL |
+ // handshake, follow up with call to CreateAndConnectSSLClientSocket() below. |
+ bool ConnectToTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { |
+ if (!StartTestServer(ssl_options)) |
+ return false; |
transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source())); |
int rv = callback_.GetResult(transport_->Connect(callback_.callback())); |
@@ -660,12 +666,12 @@ class SSLClientSocketTest : public PlatformTest { |
SSLClientSocketContext context_; |
scoped_ptr<SSLClientSocket> sock_; |
CapturingNetLog log_; |
+ AddressList addr_; |
+ scoped_ptr<SpawnedTestServer> test_server_; |
private: |
scoped_ptr<StreamSocket> transport_; |
- scoped_ptr<SpawnedTestServer> test_server_; |
TestCompletionCallback callback_; |
- AddressList addr_; |
}; |
// Verifies the correctness of GetSSLCertRequestInfo. |
@@ -713,58 +719,66 @@ class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { |
class SSLClientSocketFalseStartTest : public SSLClientSocketTest { |
protected: |
- void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options, |
- const SSLConfig& client_config, |
- bool expect_false_start) { |
- SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
- server_options, |
- base::FilePath()); |
- ASSERT_TRUE(test_server.Start()); |
- |
- AddressList addr; |
- ASSERT_TRUE(test_server.GetAddressList(&addr)); |
- |
- TestCompletionCallback callback; |
+ void CreateAndConnectUpToServerFinished( |
Ryan Sleevi
2014/05/31 00:46:11
s/UpToServerFinished/UntilServerFinishedReceived?
davidben
2014/06/02 18:45:38
Done.
|
+ const SSLConfig& client_config, |
+ TestCompletionCallback* callback, |
+ FakeBlockingStreamSocket** out_raw_transport, |
Ryan Sleevi
2014/05/31 00:46:11
More documentation is needed here. My red alert al
davidben
2014/06/02 18:45:38
Documented. (The FakeBlockingStreamSocket annoying
|
+ scoped_ptr<SSLClientSocket>* out_sock) { |
scoped_ptr<StreamSocket> real_transport( |
- new TCPClientSocket(addr, NULL, NetLog::Source())); |
+ new TCPClientSocket(addr_, NULL, NetLog::Source())); |
scoped_ptr<FakeBlockingStreamSocket> transport( |
new FakeBlockingStreamSocket(real_transport.Pass())); |
- int rv = callback.GetResult(transport->Connect(callback.callback())); |
+ int rv = callback->GetResult(transport->Connect(callback->callback())); |
EXPECT_EQ(OK, rv); |
FakeBlockingStreamSocket* raw_transport = transport.get(); |
- scoped_ptr<SSLClientSocket> sock( |
+ scoped_ptr<SSLClientSocket> sock = |
CreateSSLClientSocket(transport.PassAs<StreamSocket>(), |
- test_server.host_port_pair(), |
- client_config)); |
+ test_server_->host_port_pair(), |
+ client_config); |
// Connect. Stop before the client processes the first server leg |
// (ServerHello, etc.) |
raw_transport->BlockReadResult(); |
- rv = sock->Connect(callback.callback()); |
+ rv = sock->Connect(callback->callback()); |
EXPECT_EQ(ERR_IO_PENDING, rv); |
raw_transport->WaitForReadResult(); |
// Release the ServerHello and wait for the client to write |
// ClientKeyExchange, etc. (A proxy for waiting for the entirety of the |
// server's leg to complete, since it may span multiple reads.) |
- EXPECT_FALSE(callback.have_result()); |
+ EXPECT_FALSE(callback->have_result()); |
raw_transport->BlockWrite(); |
raw_transport->UnblockReadResult(); |
raw_transport->WaitForWrite(); |
// And, finally, release that and block the next server leg |
- // (ChangeCipherSpec, Finished). Note: callback.have_result() may or may not |
- // be true at this point depending on whether the SSL implementation waits |
- // for the client second leg to clear the internal write buffer and hit the |
- // network. |
+ // (ChangeCipherSpec, Finished). Note: callback->have_result() may or may |
+ // not be true at this point depending on whether the SSL implementation |
+ // waits for the client second leg to clear the internal write buffer and |
+ // hit the network. |
raw_transport->BlockReadResult(); |
raw_transport->UnblockWrite(); |
+ *out_raw_transport = raw_transport; |
+ *out_sock = sock.Pass(); |
+ } |
+ |
+ void TestFalseStart(const SpawnedTestServer::SSLOptions& server_options, |
+ const SSLConfig& client_config, |
+ bool expect_false_start) { |
+ ASSERT_TRUE(StartTestServer(server_options)); |
+ |
+ TestCompletionCallback callback; |
+ FakeBlockingStreamSocket* raw_transport; |
+ scoped_ptr<SSLClientSocket> sock; |
+ CreateAndConnectUpToServerFinished( |
+ client_config, &callback, &raw_transport, &sock); |
Ryan Sleevi
2014/05/31 00:46:11
DANGER: If you ever added an ASSERT_() to CreateAn
davidben
2014/06/02 18:45:38
Oh, so that's how you do it... done.
|
+ |
if (expect_false_start) { |
// When False Starting, the handshake should complete before receiving the |
// Change Cipher Spec and Finished messages. |
- rv = callback.GetResult(rv); |
+ int rv = callback.GetResult(ERR_IO_PENDING); |
Ryan Sleevi
2014/05/31 00:46:11
Just use
int rv = callback.WaitForResult();
no n
davidben
2014/06/02 18:45:38
Done.
|
EXPECT_EQ(OK, rv); |
EXPECT_TRUE(sock->IsConnected()); |
@@ -2482,6 +2496,75 @@ TEST_F(SSLClientSocketFalseStartTest, NoForwardSecrecy) { |
TestFalseStart(server_options, client_config, false); |
} |
+// Test that sessions are resumable after receiving the server Finished message. |
+TEST_F(SSLClientSocketFalseStartTest, SessionResumption) { |
+ // Start a server. |
+ SpawnedTestServer::SSLOptions server_options; |
+ server_options.key_exchanges = |
+ SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; |
+ server_options.enable_npn = true; |
+ SSLConfig client_config; |
+ client_config.next_protos.push_back("http/1.1"); |
+ |
+ // Let a full handshake complete with False Start. |
+ TestFalseStart(server_options, client_config, true); |
+ |
+ // Make a second connection. |
+ TestCompletionCallback callback; |
+ scoped_ptr<StreamSocket> transport2( |
+ new TCPClientSocket(addr_, &log_, NetLog::Source())); |
+ EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback()))); |
+ scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket( |
+ transport2.Pass(), test_server_->host_port_pair(), client_config); |
+ EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback()))); |
+ |
+ // It should resume the session. |
+ SSLInfo ssl_info; |
+ EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info)); |
+ EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type); |
+} |
+ |
+// Test that sessions are not resumable before receiving the server Finished |
+// message. |
+TEST_F(SSLClientSocketFalseStartTest, NoSessionResumptionBeforeFinish) { |
+ // Start a server. |
+ SpawnedTestServer::SSLOptions server_options; |
+ server_options.key_exchanges = |
+ SpawnedTestServer::SSLOptions::KEY_EXCHANGE_DHE_RSA; |
+ server_options.enable_npn = true; |
+ ASSERT_TRUE(StartTestServer(server_options)); |
+ |
+ SSLConfig client_config; |
+ client_config.next_protos.push_back("http/1.1"); |
+ |
+ // Start a handshake up to the server Finished message. |
+ TestCompletionCallback callback; |
+ FakeBlockingStreamSocket* raw_transport1; |
+ scoped_ptr<SSLClientSocket> sock1; |
+ CreateAndConnectUpToServerFinished( |
+ client_config, &callback, &raw_transport1, &sock1); |
+ // The handshake should False Start. |
+ EXPECT_EQ(OK, callback.GetResult(ERR_IO_PENDING)); |
Ryan Sleevi
2014/05/31 00:46:11
ditto WaitForResult()
However, it's unclear to me
davidben
2014/06/02 18:45:38
Done. Also added a comment.
|
+ |
+ // Drop the old socket. This is needed because the Python test server can't |
+ // service two sockets in parallel. |
+ sock1.reset(); |
+ |
+ // Before the first connection receives ServerFinished, start a second |
+ // connection. |
+ scoped_ptr<StreamSocket> transport2( |
+ new TCPClientSocket(addr_, &log_, NetLog::Source())); |
+ EXPECT_EQ(OK, callback.GetResult(transport2->Connect(callback.callback()))); |
+ scoped_ptr<SSLClientSocket> sock2 = CreateSSLClientSocket( |
+ transport2.Pass(), test_server_->host_port_pair(), client_config); |
+ EXPECT_EQ(OK, callback.GetResult(sock2->Connect(callback.callback()))); |
+ |
+ // No session resumption. |
+ SSLInfo ssl_info; |
+ EXPECT_TRUE(sock2->GetSSLInfo(&ssl_info)); |
+ EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type); |
+} |
+ |
// Connect to a server using channel id. It should allow the connection. |
TEST_F(SSLClientSocketChannelIDTest, SendChannelID) { |
SpawnedTestServer::SSLOptions ssl_options; |