| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/socket/ssl_client_socket.h" | 5 #include "net/socket/ssl_client_socket.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "net/base/address_list.h" | 10 #include "net/base/address_list.h" |
| (...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 | 1167 |
| 1168 if (rv == ERR_IO_PENDING) | 1168 if (rv == ERR_IO_PENDING) |
| 1169 rv = callback.WaitForResult(); | 1169 rv = callback.WaitForResult(); |
| 1170 | 1170 |
| 1171 EXPECT_GE(rv, 0); | 1171 EXPECT_GE(rv, 0); |
| 1172 if (rv <= 0) | 1172 if (rv <= 0) |
| 1173 break; | 1173 break; |
| 1174 } | 1174 } |
| 1175 } | 1175 } |
| 1176 | 1176 |
| 1177 // Tests that SSLClientSocket properly handle when the underlying transport |
| 1178 // synchronously returns an error code on read failure. The error code should be |
| 1179 // echoed back so SSLv3 fallback logic can condition on it. |
| 1180 TEST_F(SSLClientSocketTest, Connect_WithSynchronousError) { |
| 1181 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1182 SpawnedTestServer::kLocalhost, |
| 1183 base::FilePath()); |
| 1184 ASSERT_TRUE(test_server.Start()); |
| 1185 |
| 1186 AddressList addr; |
| 1187 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| 1188 |
| 1189 TestCompletionCallback callback; |
| 1190 scoped_ptr<StreamSocket> real_transport( |
| 1191 new TCPClientSocket(addr, NULL, NetLog::Source())); |
| 1192 scoped_ptr<SynchronousErrorStreamSocket> transport( |
| 1193 new SynchronousErrorStreamSocket(real_transport.Pass())); |
| 1194 int rv = callback.GetResult(transport->Connect(callback.callback())); |
| 1195 EXPECT_EQ(OK, rv); |
| 1196 |
| 1197 // Disable TLS False Start to avoid handshake non-determinism. |
| 1198 SSLConfig ssl_config; |
| 1199 ssl_config.false_start_enabled = false; |
| 1200 |
| 1201 SynchronousErrorStreamSocket* raw_transport = transport.get(); |
| 1202 scoped_ptr<SSLClientSocket> sock( |
| 1203 CreateSSLClientSocket(transport.PassAs<StreamSocket>(), |
| 1204 test_server.host_port_pair(), |
| 1205 ssl_config)); |
| 1206 |
| 1207 raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); |
| 1208 |
| 1209 rv = callback.GetResult(sock->Connect(callback.callback())); |
| 1210 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1211 EXPECT_FALSE(sock->IsConnected()); |
| 1212 } |
| 1213 |
| 1177 // Tests that the SSLClientSocket properly handles when the underlying transport | 1214 // Tests that the SSLClientSocket properly handles when the underlying transport |
| 1178 // synchronously returns an error code - such as if an intermediary terminates | 1215 // synchronously returns an error code - such as if an intermediary terminates |
| 1179 // the socket connection uncleanly. | 1216 // the socket connection uncleanly. |
| 1180 // This is a regression test for http://crbug.com/238536 | 1217 // This is a regression test for http://crbug.com/238536 |
| 1181 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { | 1218 TEST_F(SSLClientSocketTest, Read_WithSynchronousError) { |
| 1182 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1219 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1183 SpawnedTestServer::kLocalhost, | 1220 SpawnedTestServer::kLocalhost, |
| 1184 base::FilePath()); | 1221 base::FilePath()); |
| 1185 ASSERT_TRUE(test_server.Start()); | 1222 ASSERT_TRUE(test_server.Start()); |
| 1186 | 1223 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 // Simulate an unclean/forcible shutdown. | 1259 // Simulate an unclean/forcible shutdown. |
| 1223 raw_transport->SetNextReadError(ERR_CONNECTION_RESET); | 1260 raw_transport->SetNextReadError(ERR_CONNECTION_RESET); |
| 1224 | 1261 |
| 1225 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); | 1262 scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
| 1226 | 1263 |
| 1227 // Note: This test will hang if this bug has regressed. Simply checking that | 1264 // Note: This test will hang if this bug has regressed. Simply checking that |
| 1228 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate | 1265 // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate |
| 1229 // result when using a dedicated task runner for NSS. | 1266 // result when using a dedicated task runner for NSS. |
| 1230 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); | 1267 rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
| 1231 | 1268 |
| 1232 #if !defined(USE_OPENSSL) | |
| 1233 // SSLClientSocketNSS records the error exactly | |
| 1234 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1269 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1235 #else | |
| 1236 // SSLClientSocketOpenSSL treats any errors as a simple EOF. | |
| 1237 EXPECT_EQ(0, rv); | |
| 1238 #endif | |
| 1239 } | 1270 } |
| 1240 | 1271 |
| 1241 // Tests that the SSLClientSocket properly handles when the underlying transport | 1272 // Tests that the SSLClientSocket properly handles when the underlying transport |
| 1242 // asynchronously returns an error code while writing data - such as if an | 1273 // asynchronously returns an error code while writing data - such as if an |
| 1243 // intermediary terminates the socket connection uncleanly. | 1274 // intermediary terminates the socket connection uncleanly. |
| 1244 // This is a regression test for http://crbug.com/249848 | 1275 // This is a regression test for http://crbug.com/249848 |
| 1245 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) { | 1276 TEST_F(SSLClientSocketTest, Write_WithSynchronousError) { |
| 1246 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1277 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1247 SpawnedTestServer::kLocalhost, | 1278 SpawnedTestServer::kLocalhost, |
| 1248 base::FilePath()); | 1279 base::FilePath()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 | 1334 |
| 1304 // Now unblock the outgoing request, having it fail with the connection | 1335 // Now unblock the outgoing request, having it fail with the connection |
| 1305 // being reset. | 1336 // being reset. |
| 1306 raw_transport->UnblockWrite(); | 1337 raw_transport->UnblockWrite(); |
| 1307 | 1338 |
| 1308 // Note: This will cause an inifite loop if this bug has regressed. Simply | 1339 // Note: This will cause an inifite loop if this bug has regressed. Simply |
| 1309 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING | 1340 // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING |
| 1310 // is a legitimate result when using a dedicated task runner for NSS. | 1341 // is a legitimate result when using a dedicated task runner for NSS. |
| 1311 rv = callback.GetResult(rv); | 1342 rv = callback.GetResult(rv); |
| 1312 | 1343 |
| 1313 #if !defined(USE_OPENSSL) | |
| 1314 // SSLClientSocketNSS records the error exactly | |
| 1315 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1344 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1316 #else | |
| 1317 // SSLClientSocketOpenSSL treats any errors as a simple EOF. | |
| 1318 EXPECT_EQ(0, rv); | |
| 1319 #endif | |
| 1320 } | 1345 } |
| 1321 | 1346 |
| 1322 // Test the full duplex mode, with Read and Write pending at the same time. | 1347 // Test the full duplex mode, with Read and Write pending at the same time. |
| 1323 // This test also serves as a regression test for http://crbug.com/29815. | 1348 // This test also serves as a regression test for http://crbug.com/29815. |
| 1324 TEST_F(SSLClientSocketTest, Read_FullDuplex) { | 1349 TEST_F(SSLClientSocketTest, Read_FullDuplex) { |
| 1325 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1350 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1326 SpawnedTestServer::kLocalhost, | 1351 SpawnedTestServer::kLocalhost, |
| 1327 base::FilePath()); | 1352 base::FilePath()); |
| 1328 ASSERT_TRUE(test_server.Start()); | 1353 ASSERT_TRUE(test_server.Start()); |
| 1329 | 1354 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 ASSERT_EQ(ERR_IO_PENDING, rv); | 1509 ASSERT_EQ(ERR_IO_PENDING, rv); |
| 1485 ASSERT_FALSE(callback.have_result()); | 1510 ASSERT_FALSE(callback.have_result()); |
| 1486 | 1511 |
| 1487 // Now unblock Write(), which will invoke OnSendComplete and (eventually) | 1512 // Now unblock Write(), which will invoke OnSendComplete and (eventually) |
| 1488 // call the Read() callback, deleting the socket and thus aborting calling | 1513 // call the Read() callback, deleting the socket and thus aborting calling |
| 1489 // the Write() callback. | 1514 // the Write() callback. |
| 1490 raw_transport->UnblockWrite(); | 1515 raw_transport->UnblockWrite(); |
| 1491 | 1516 |
| 1492 rv = read_callback.WaitForResult(); | 1517 rv = read_callback.WaitForResult(); |
| 1493 | 1518 |
| 1494 #if !defined(USE_OPENSSL) | |
| 1495 // NSS records the error exactly. | |
| 1496 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1519 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1497 #else | |
| 1498 // OpenSSL treats any errors as a simple EOF. | |
| 1499 EXPECT_EQ(0, rv); | |
| 1500 #endif | |
| 1501 | 1520 |
| 1502 // The Write callback should not have been called. | 1521 // The Write callback should not have been called. |
| 1503 EXPECT_FALSE(callback.have_result()); | 1522 EXPECT_FALSE(callback.have_result()); |
| 1504 } | 1523 } |
| 1505 | 1524 |
| 1506 // Tests that the SSLClientSocket does not crash if data is received on the | 1525 // Tests that the SSLClientSocket does not crash if data is received on the |
| 1507 // transport socket after a failing write. This can occur if we have a Write | 1526 // transport socket after a failing write. This can occur if we have a Write |
| 1508 // error in a SPDY socket. | 1527 // error in a SPDY socket. |
| 1509 // Regression test for http://crbug.com/335557 | 1528 // Regression test for http://crbug.com/335557 |
| 1510 TEST_F(SSLClientSocketTest, Read_WithWriteError) { | 1529 TEST_F(SSLClientSocketTest, Read_WithWriteError) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 rv = callback.GetResult(sock->Write(long_request_buffer.get(), | 1604 rv = callback.GetResult(sock->Write(long_request_buffer.get(), |
| 1586 long_request_buffer->BytesRemaining(), | 1605 long_request_buffer->BytesRemaining(), |
| 1587 callback.callback())); | 1606 callback.callback())); |
| 1588 if (rv > 0) { | 1607 if (rv > 0) { |
| 1589 long_request_buffer->DidConsume(rv); | 1608 long_request_buffer->DidConsume(rv); |
| 1590 // Abort if the entire buffer is ever consumed. | 1609 // Abort if the entire buffer is ever consumed. |
| 1591 ASSERT_LT(0, long_request_buffer->BytesRemaining()); | 1610 ASSERT_LT(0, long_request_buffer->BytesRemaining()); |
| 1592 } | 1611 } |
| 1593 } while (rv > 0); | 1612 } while (rv > 0); |
| 1594 | 1613 |
| 1595 #if !defined(USE_OPENSSL) | |
| 1596 // NSS records the error exactly. | |
| 1597 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1614 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1598 #else | |
| 1599 // OpenSSL treats the reset as a generic protocol error. | |
| 1600 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv); | |
| 1601 #endif | |
| 1602 | 1615 |
| 1603 // Release the read. Some bytes should go through. | 1616 // Release the read. |
| 1604 raw_transport->UnblockReadResult(); | 1617 raw_transport->UnblockReadResult(); |
| 1605 rv = read_callback.WaitForResult(); | 1618 rv = read_callback.WaitForResult(); |
| 1606 | 1619 |
| 1607 // Per the fix for http://crbug.com/249848, write failures currently break | 1620 #if defined(USE_OPENSSL) |
| 1608 // reads. Change this assertion if they're changed to not collide. | 1621 // Should still read bytes despite the write error. |
| 1622 EXPECT_LT(0, rv); |
| 1623 #else |
| 1624 // NSS attempts to flush the write buffer in PR_Read on an SSL socket before |
| 1625 // pumping the read state machine, unless configured with SSL_ENABLE_FDX, so |
| 1626 // the write error bleeds into the read. |
| 1609 EXPECT_EQ(ERR_CONNECTION_RESET, rv); | 1627 EXPECT_EQ(ERR_CONNECTION_RESET, rv); |
| 1628 #endif |
| 1610 } | 1629 } |
| 1611 | 1630 |
| 1612 TEST_F(SSLClientSocketTest, Read_SmallChunks) { | 1631 TEST_F(SSLClientSocketTest, Read_SmallChunks) { |
| 1613 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, | 1632 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
| 1614 SpawnedTestServer::kLocalhost, | 1633 SpawnedTestServer::kLocalhost, |
| 1615 base::FilePath()); | 1634 base::FilePath()); |
| 1616 ASSERT_TRUE(test_server.Start()); | 1635 ASSERT_TRUE(test_server.Start()); |
| 1617 | 1636 |
| 1618 AddressList addr; | 1637 AddressList addr; |
| 1619 ASSERT_TRUE(test_server.GetAddressList(&addr)); | 1638 ASSERT_TRUE(test_server.GetAddressList(&addr)); |
| (...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2632 | 2651 |
| 2633 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns | 2652 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns |
| 2634 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all | 2653 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all |
| 2635 // error codes for now. | 2654 // error codes for now. |
| 2636 // http://crbug.com/373670 | 2655 // http://crbug.com/373670 |
| 2637 EXPECT_NE(OK, rv); | 2656 EXPECT_NE(OK, rv); |
| 2638 EXPECT_FALSE(sock_->IsConnected()); | 2657 EXPECT_FALSE(sock_->IsConnected()); |
| 2639 } | 2658 } |
| 2640 | 2659 |
| 2641 } // namespace net | 2660 } // namespace net |
| OLD | NEW |