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

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: rsleevi comments 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 770 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 1345
1313 #if !defined(USE_OPENSSL) 1346 #if !defined(USE_OPENSSL)
1314 // SSLClientSocketNSS records the error exactly 1347 // SSLClientSocketNSS records the error exactly
1315 EXPECT_EQ(ERR_CONNECTION_RESET, rv); 1348 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
1316 #else 1349 #else
1317 // SSLClientSocketOpenSSL treats any errors as a simple EOF. 1350 // SSLClientSocketOpenSSL treats any errors as a simple EOF.
1318 EXPECT_EQ(0, rv); 1351 EXPECT_EQ(0, rv);
1319 #endif 1352 #endif
1320 } 1353 }
1321 1354
1355 // If there is a Write failure at the transport with no follow-up Read, although
1356 // the write error will not be returned to the client until a future Read or
1357 // Write operation, SSLClientSocket should not spin attempting to re-write on
1358 // the socket. This is a regression test for part of https://crbug.com/381160.
1359 TEST_F(SSLClientSocketTest, Write_WithSynchronousErrorNoRead) {
1360 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1361 SpawnedTestServer::kLocalhost,
1362 base::FilePath());
1363 ASSERT_TRUE(test_server.Start());
1364
1365 AddressList addr;
1366 ASSERT_TRUE(test_server.GetAddressList(&addr));
1367
1368 TestCompletionCallback callback;
1369 scoped_ptr<StreamSocket> real_transport(
1370 new TCPClientSocket(addr, NULL, NetLog::Source()));
1371 // Note: intermediate sockets' ownership are handed to |sock|, but a pointer
1372 // is retained in order to query them.
1373 scoped_ptr<SynchronousErrorStreamSocket> error_socket(
1374 new SynchronousErrorStreamSocket(real_transport.Pass()));
1375 SynchronousErrorStreamSocket* raw_error_socket = error_socket.get();
1376 scoped_ptr<CountingStreamSocket> counting_socket(
1377 new CountingStreamSocket(error_socket.PassAs<StreamSocket>()));
1378 CountingStreamSocket* raw_counting_socket = counting_socket.get();
1379 int rv = callback.GetResult(counting_socket->Connect(callback.callback()));
1380 EXPECT_EQ(OK, rv);
Ryan Sleevi 2014/06/17 19:43:39 Seems like you might want this to be ASSERT_EQ (di
davidben 2014/06/17 20:27:43 Done.
1381
1382 // Disable TLS False Start to avoid handshake non-determinism.
1383 SSLConfig ssl_config;
1384 ssl_config.false_start_enabled = false;
1385
1386 scoped_ptr<SSLClientSocket> sock(
1387 CreateSSLClientSocket(counting_socket.PassAs<StreamSocket>(),
1388 test_server.host_port_pair(),
1389 ssl_config));
1390
1391 rv = callback.GetResult(sock->Connect(callback.callback()));
1392 EXPECT_EQ(OK, rv);
1393 EXPECT_TRUE(sock->IsConnected());
1394
1395 // Simulate an unclean/forcible shutdown on the underlying socket.
1396 raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET);
1397
1398 const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
1399 static const int kRequestTextSize =
1400 static_cast<int>(arraysize(request_text) - 1);
1401 scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize));
1402 memcpy(request_buffer->data(), request_text, kRequestTextSize);
1403
1404 // This write should complete synchronously, because the TLS ciphertext
1405 // can be created and placed into the outgoing buffers independent of the
1406 // underlying transport.
1407 rv = callback.GetResult(
1408 sock->Write(request_buffer.get(), kRequestTextSize, callback.callback()));
1409 EXPECT_EQ(kRequestTextSize, rv);
1410
1411 // Let the event loop spin for a little bit of time. Even on platforms where
1412 // pumping the state machine involve thread hops, there should be no further
1413 // writes on the transport socket.
1414 int old_write_count = raw_counting_socket->write_count();
1415 base::RunLoop loop;
1416 base::MessageLoop::current()->PostDelayedTask(
1417 FROM_HERE, loop.QuitClosure(), base::TimeDelta::FromMilliseconds(100));
1418 loop.Run();
Ryan Sleevi 2014/06/17 00:56:32 What about using RunUntilIdle here? Or explicitly
davidben 2014/06/17 20:27:43 Hrm. I'm... not sure if it works. There's a lot of
1419 EXPECT_EQ(old_write_count, raw_counting_socket->write_count());
1420 }
1421
1322 // Test the full duplex mode, with Read and Write pending at the same time. 1422 // 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. 1423 // This test also serves as a regression test for http://crbug.com/29815.
1324 TEST_F(SSLClientSocketTest, Read_FullDuplex) { 1424 TEST_F(SSLClientSocketTest, Read_FullDuplex) {
1325 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, 1425 SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
1326 SpawnedTestServer::kLocalhost, 1426 SpawnedTestServer::kLocalhost,
1327 base::FilePath()); 1427 base::FilePath());
1328 ASSERT_TRUE(test_server.Start()); 1428 ASSERT_TRUE(test_server.Start());
1329 1429
1330 AddressList addr; 1430 AddressList addr;
1331 ASSERT_TRUE(test_server.GetAddressList(&addr)); 1431 ASSERT_TRUE(test_server.GetAddressList(&addr));
(...skipping 1300 matching lines...) Expand 10 before | Expand all | Expand 10 after
2632 2732
2633 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns 2733 // TODO(haavardm@opera.com): Due to differences in threading, Linux returns
2634 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all 2734 // ERR_UNEXPECTED while Mac and Windows return ERR_PROTOCOL_ERROR. Accept all
2635 // error codes for now. 2735 // error codes for now.
2636 // http://crbug.com/373670 2736 // http://crbug.com/373670
2637 EXPECT_NE(OK, rv); 2737 EXPECT_NE(OK, rv);
2638 EXPECT_FALSE(sock_->IsConnected()); 2738 EXPECT_FALSE(sock_->IsConnected());
2639 } 2739 }
2640 2740
2641 } // namespace net 2741 } // 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