Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: net/socket/ssl_client_socket_unittest.cc

Issue 337823002: Stop attempting to write to transport sockets in NSS on failure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: document CountingStreamSocket (try jobs on patch set 1) Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/time/time.h"
10 #include "net/base/address_list.h" 11 #include "net/base/address_list.h"
11 #include "net/base/io_buffer.h" 12 #include "net/base/io_buffer.h"
12 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
13 #include "net/base/net_log.h" 14 #include "net/base/net_log.h"
14 #include "net/base/net_log_unittest.h" 15 #include "net/base/net_log_unittest.h"
15 #include "net/base/test_completion_callback.h" 16 #include "net/base/test_completion_callback.h"
16 #include "net/base/test_data_directory.h" 17 #include "net/base/test_data_directory.h"
17 #include "net/cert/mock_cert_verifier.h" 18 #include "net/cert/mock_cert_verifier.h"
18 #include "net/cert/test_root_certs.h" 19 #include "net/cert/test_root_certs.h"
19 #include "net/dns/host_resolver.h" 20 #include "net/dns/host_resolver.h"
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 // Stop the WaitForReadResult() call if any. 523 // Stop the WaitForReadResult() call if any.
523 if (read_loop_) 524 if (read_loop_)
524 read_loop_->Quit(); 525 read_loop_->Quit();
525 } else { 526 } else {
526 // Either the Read() was never blocked or UnblockReadResult() was called 527 // Either the Read() was never blocked or UnblockReadResult() was called
527 // before the Read() completed. Either way, run the callback. 528 // before the Read() completed. Either way, run the callback.
528 base::ResetAndReturn(&pending_read_callback_).Run(result); 529 base::ResetAndReturn(&pending_read_callback_).Run(result);
529 } 530 }
530 } 531 }
531 532
533 // CountingStreamSocket wraps an existing StreamSocket and maintains a count of
534 // reads and writes on the socket.
535 class CountingStreamSocket : public WrappedStreamSocket {
536 public:
537 explicit CountingStreamSocket(scoped_ptr<StreamSocket> transport)
538 : WrappedStreamSocket(transport.Pass()),
539 read_count_(0),
540 write_count_(0) {}
541 virtual ~CountingStreamSocket() {}
542
543 // Socket implementation:
544 virtual int Read(IOBuffer* buf,
545 int buf_len,
546 const CompletionCallback& callback) OVERRIDE {
547 read_count_++;
548 return transport_->Read(buf, buf_len, callback);
549 }
550 virtual int Write(IOBuffer* buf,
551 int buf_len,
552 const CompletionCallback& callback) OVERRIDE {
553 write_count_++;
554 return transport_->Write(buf, buf_len, callback);
555 }
556
557 int read_count() const { return read_count_; }
558 int write_count() const { return write_count_; }
559
560 private:
561 int read_count_;
562 int write_count_;
563 };
564
532 // CompletionCallback that will delete the associated StreamSocket when 565 // CompletionCallback that will delete the associated StreamSocket when
533 // the callback is invoked. 566 // the callback is invoked.
534 class DeleteSocketCallback : public TestCompletionCallbackBase { 567 class DeleteSocketCallback : public TestCompletionCallbackBase {
535 public: 568 public:
536 explicit DeleteSocketCallback(StreamSocket* socket) 569 explicit DeleteSocketCallback(StreamSocket* socket)
537 : socket_(socket), 570 : socket_(socket),
538 callback_(base::Bind(&DeleteSocketCallback::OnComplete, 571 callback_(base::Bind(&DeleteSocketCallback::OnComplete,
539 base::Unretained(this))) {} 572 base::Unretained(this))) {}
540 virtual ~DeleteSocketCallback() {} 573 virtual ~DeleteSocketCallback() {}
541 574
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 1307
1275 #if !defined(USE_OPENSSL) 1308 #if !defined(USE_OPENSSL)
1276 // SSLClientSocketNSS records the error exactly 1309 // SSLClientSocketNSS records the error exactly
1277 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1310 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1278 #else 1311 #else
1279 // SSLClientSocketOpenSSL treats any errors as a simple EOF. 1312 // SSLClientSocketOpenSSL treats any errors as a simple EOF.
1280 EXPECT_EQ(0, rv); 1313 EXPECT_EQ(0, rv);
1281 #endif 1314 #endif
1282 } 1315 }
1283 1316
1317 // If there is a Write failure at the transport with no follow-up Read, although
1318 // the write error will not be returned to the client until a future Read or
1319 // Write operation, SSLClientSocket should not spin attempting to re-write on
1320 // the socket. This is a regression test for part of https://crbug.com/381160.
1321 TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) {
1322 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1323 SpawnedTestServer::kLocalhost,
1324 base::FilePath());
1325 ASSERT_TRUE(test_server.Start());
1326
1327 AddressList addr;
1328 ASSERT_TRUE(test_server.GetAddressList(&addr));
1329
1330 TestCompletionCallback callback;
1331 scoped_ptr<StreamSocket> real_transport(
1332 new TCPClientSocket(addr, NULL, NetLog::Source()));
1333 // Note: intermediate sockets' ownership are handed to |sock|, but a pointer
1334 // is retained in order to query them.
1335 scoped_ptr<SynchronousErrorStreamSocket> error_socket(
1336 new SynchronousErrorStreamSocket(real_transport.Pass()));
1337 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
1338 scoped_ptr<CountingStreamSocket> counting_socket(
1339 new CountingStreamSocket(error_socket.PassAs<StreamSocket>()));
1340 CountingStreamSocket* raw_counting_socket = counting_socket.get();
1341 int rv = callback.GetResult(counting_socket->Connect(callback.callback()));
1342 EXPECT_EQ(OK, rv);
1343
1344 // Disable TLS False Start to avoid handshake non-determinism.
1345 SSLConfig ssl_config;
1346 ssl_config.false_start_enabled = false;
1347
1348 scoped_ptr<SSLClientSocket> sock(
1349 CreateSSLClientSocket(counting_socket.PassAs<StreamSocket>(),
1350 test_server.host_port_pair(),
1351 ssl_config));
1352
1353 rv = callback.GetResult(sock->Connect(callback.callback()));
1354 EXPECT_EQ(OK, rv);
1355 EXPECT_TRUE(sock->IsConnected());
1356
1357 // Simulate an unclean/forcible shutdown on the underlying socket.
1358 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
1359
1360 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
1361 static const int kRequestTextSize =
1362 static_cast<int>(arraysize(request_text) - 1);
1363 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
1364 memcpy(request_buffer->data(), request_text, kRequestTextSize);
1365
1366 // This write should complete synchronously, because the TLS ciphertext
1367 // can be created and placed into the outgoing buffers independent of the
1368 // underlying transport.
1369 rv = callback.GetResult(
1370 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback()));
1371 EXPECT_EQ(kRequestTextSize, rv);
1372
1373 // Let the event loop spin for a little bit of time. Even on platforms where
1374 // pumping the state machine involve thread hops, there should be no further
1375 // writes on the transport socket.
1376 int old_write_count = raw_counting_socket->write_count();
1377 base::RunLoop loop;
1378 base::MessageLoop::current()->PostDelayedTask(
1379 FROM_HERE, loop.QuitClosure(), base::TimeDelta::FromMilliseconds(100));
wtc 2014/06/16 19:57:21 IMPORTANT: could this be a source of test flakines
davidben 2014/06/16 23:02:13 Yeah, it might flakily pass when it shouldn't, but
1380 loop.Run();
1381 EXPECT_EQ(old_write_count, raw_counting_socket->write_count());
1382 }
1383
1284 // Test the full duplex mode, with Read and Write pending at the same time. 1384 // Test the full duplex mode, with Read and Write pending at the same time.
1285 // This test also serves as a regression test for http://crbug.com/29815. 1385 // This test also serves as a regression test for http://crbug.com/29815.
1286 TEST_F(SSLClientSocketTest, Read_FullDuplex) { 1386 TEST_F(SSLClientSocketTest, Read_FullDuplex) {
1287 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1387 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1288 SpawnedTestServer::kLocalhost, 1388 SpawnedTestServer::kLocalhost,
1289 base::FilePath()); 1389 base::FilePath());
1290 ASSERT_TRUE(test_server.Start()); 1390 ASSERT_TRUE(test_server.Start());
1291 1391
1292 AddressList addr; 1392 AddressList addr;
1293 ASSERT_TRUE(test_server.GetAddressList(&addr)); 1393 ASSERT_TRUE(test_server.GetAddressList(&addr));
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 2619
2520 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns 2620 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns
2521 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all 2621 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all
2522 // error codes for now. 2622 // error codes for now.
2523 // http://crbug.com/373670 2623 // http://crbug.com/373670
2524 EXPECT_NE(OK, rv); 2624 EXPECT_NE(OK, rv);
2525 EXPECT_FALSE(sock_->IsConnected()); 2625 EXPECT_FALSE(sock_->IsConnected());
2526 } 2626 }
2527 2627
2528 } // namespace net 2628 } // namespace net
OLDNEW
« net/socket/ssl_client_socket_nss.cc ('K') | « net/socket/ssl_client_socket_nss.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698