diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-12 23:02:31 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-12 23:02:31 +0000 |
commit | 11203f01dc03d31b89558b9cba0cf3ffe4d6511c (patch) | |
tree | 20a721f07e6ddbd29d2fe87792e6a3b17349bab1 /net/socket | |
parent | 8f4752537eeff04982fddbbf4bd6bf92fd1ab9e1 (diff) | |
download | chromium_src-11203f01dc03d31b89558b9cba0cf3ffe4d6511c.zip chromium_src-11203f01dc03d31b89558b9cba0cf3ffe4d6511c.tar.gz chromium_src-11203f01dc03d31b89558b9cba0cf3ffe4d6511c.tar.bz2 |
After draining the body of a 401/407 response, verify that
the keep-alive connection is still connected and idle before
reusing it for authentication restart. An impatient server
may have closed the connection while waiting for the user to
enter the username and password.
In socket_test_util.cc, return the mock ERR_UNEXPECTED error
synchronously.
R=eroman
BUG=21675
TEST=new unit test
Review URL: http://codereview.chromium.org/389007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31846 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r-- | net/socket/socket_test_util.cc | 19 | ||||
-rw-r--r-- | net/socket/socket_test_util.h | 18 |
2 files changed, 33 insertions, 4 deletions
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 239a81d..ac9411e 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc @@ -66,8 +66,9 @@ MockTCPClientSocket::MockTCPClientSocket(const net::AddressList& addresses, : addresses_(addresses), data_(data), read_offset_(0), - read_data_(true, net::ERR_UNEXPECTED), + read_data_(false, net::ERR_UNEXPECTED), need_read_data_(true), + peer_closed_connection_(false), pending_buf_(NULL), pending_buf_len_(0), pending_callback_(NULL) { @@ -87,9 +88,13 @@ int MockTCPClientSocket::Connect(net::CompletionCallback* callback, return data_->connect_data().result; } +bool MockTCPClientSocket::IsConnected() const { + return connected_ && !peer_closed_connection_; +} + int MockTCPClientSocket::Read(net::IOBuffer* buf, int buf_len, net::CompletionCallback* callback) { - if (!IsConnected()) + if (!connected_) return net::ERR_UNEXPECTED; // If the buffer is already in use, a read is already in progress! @@ -102,6 +107,12 @@ int MockTCPClientSocket::Read(net::IOBuffer* buf, int buf_len, if (need_read_data_) { read_data_ = data_->GetNextRead(); + if (read_data_.result == ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { + // This MockRead is just a marker to instruct us to set + // peer_closed_connection_. Skip it and get the next one. + read_data_ = data_->GetNextRead(); + peer_closed_connection_ = true; + } // ERR_IO_PENDING means that the SocketDataProvider is taking responsibility // to complete the async IO manually later (via OnReadComplete). if (read_data_.result == ERR_IO_PENDING) { @@ -119,7 +130,7 @@ int MockTCPClientSocket::Write(net::IOBuffer* buf, int buf_len, DCHECK(buf); DCHECK_GT(buf_len, 0); - if (!IsConnected()) + if (!connected_) return net::ERR_UNEXPECTED; std::string data(buf->data(), buf_len); @@ -304,7 +315,7 @@ DynamicSocketDataProvider::DynamicSocketDataProvider() MockRead DynamicSocketDataProvider::GetNextRead() { if (reads_.empty()) - return MockRead(true, ERR_UNEXPECTED); + return MockRead(false, ERR_UNEXPECTED); MockRead result = reads_.front(); if (short_read_limit_ == 0 || result.data_len <= short_read_limit_) { reads_.pop_front(); diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index c369435..d16dcb4 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h @@ -25,6 +25,15 @@ namespace net { +enum { + // A private network error code used by the socket test utility classes. + // If the |result| member of a MockRead is + // ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, that MockRead is just a + // marker that indicates the peer will close the connection after the next + // MockRead. The other members of that MockRead are ignored. + ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ = -10000, +}; + class ClientSocket; class LoadLog; class MockClientSocket; @@ -285,6 +294,8 @@ class MockClientSocket : public net::SSLClientSocket { void RunCallback(net::CompletionCallback*, int result); ScopedRunnableMethodFactory<MockClientSocket> method_factory_; + + // True if Connect completed successfully and Disconnect hasn't been called. bool connected_; }; @@ -296,6 +307,8 @@ class MockTCPClientSocket : public MockClientSocket { // ClientSocket methods: virtual int Connect(net::CompletionCallback* callback, LoadLog* load_log); + virtual bool IsConnected() const; + virtual bool IsConnectedAndIdle() const { return IsConnected(); } // Socket methods: virtual int Read(net::IOBuffer* buf, int buf_len, @@ -317,6 +330,11 @@ class MockTCPClientSocket : public MockClientSocket { net::MockRead read_data_; bool need_read_data_; + // True if the peer has closed the connection. This allows us to simulate + // the recv(..., MSG_PEEK) call in the IsConnectedAndIdle method of the real + // TCPClientSocket. + bool peer_closed_connection_; + // While an asynchronous IO is pending, we save our user-buffer state. net::IOBuffer* pending_buf_; int pending_buf_len_; |