diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 09:35:30 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-16 09:35:30 +0000 |
commit | 3d6ddbadc0c670fa3db69f7173a67da09f9f1a12 (patch) | |
tree | aa1cc86f6426f6607360670e21023969f697f16d /chrome | |
parent | 387a6ceae16e24b7ed19dc143f97c3378ca343df (diff) | |
download | chromium_src-3d6ddbadc0c670fa3db69f7173a67da09f9f1a12.zip chromium_src-3d6ddbadc0c670fa3db69f7173a67da09f9f1a12.tar.gz chromium_src-3d6ddbadc0c670fa3db69f7173a67da09f9f1a12.tar.bz2 |
Moved ChromeAsyncSocket to jingle/notifier/base.
Fixed some signed/unsigned warnings.
BUG=45612
TEST=existing unittests
Review URL: http://codereview.chromium.org/2857039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52638 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/sync/tools/chrome_async_socket.cc | 478 | ||||
-rw-r--r-- | chrome/browser/sync/tools/chrome_async_socket.h | 226 | ||||
-rw-r--r-- | chrome/browser/sync/tools/chrome_async_socket_unittest.cc | 1015 | ||||
-rw-r--r-- | chrome/browser/sync/tools/sync_listen_notifications.cc | 4 | ||||
-rw-r--r-- | chrome/browser/sync/tools/sync_tools.gyp | 46 |
5 files changed, 2 insertions, 1767 deletions
diff --git a/chrome/browser/sync/tools/chrome_async_socket.cc b/chrome/browser/sync/tools/chrome_async_socket.cc deleted file mode 100644 index e5d662f..0000000 --- a/chrome/browser/sync/tools/chrome_async_socket.cc +++ /dev/null @@ -1,478 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/sync/tools/chrome_async_socket.h" - -#if defined(OS_WIN) -#include <winsock2.h> -#elif defined(OS_POSIX) -#include <arpa/inet.h> -#endif - -#include <algorithm> -#include <cstring> -#include <cstdlib> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "net/base/address_list.h" -#include "net/base/io_buffer.h" -#include "net/base/ssl_config_service.h" -#include "net/base/sys_addrinfo.h" -#include "net/socket/client_socket_factory.h" -#include "net/socket/ssl_client_socket.h" -#include "net/socket/tcp_client_socket.h" -#include "talk/base/socketaddress.h" - -namespace sync_tools { - -ChromeAsyncSocket::ChromeAsyncSocket( - net::ClientSocketFactory* client_socket_factory, - const net::SSLConfig& ssl_config, - size_t read_buf_size, - size_t write_buf_size, - net::NetLog* net_log) - : connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), - &ChromeAsyncSocket::ProcessConnectDone), - read_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), - &ChromeAsyncSocket::ProcessReadDone), - write_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), - &ChromeAsyncSocket::ProcessWriteDone), - ssl_connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), - &ChromeAsyncSocket::ProcessSSLConnectDone), - client_socket_factory_(client_socket_factory), - ssl_config_(ssl_config), - bound_net_log_( - net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), - state_(STATE_CLOSED), - error_(ERROR_NONE), - net_error_(net::OK), - scoped_runnable_method_factory_( - ALLOW_THIS_IN_INITIALIZER_LIST(this)), - read_state_(IDLE), - read_buf_(new net::IOBufferWithSize(read_buf_size)), - read_start_(0), - read_end_(0), - write_state_(IDLE), - write_buf_(new net::IOBufferWithSize(write_buf_size)), - write_end_(0) { - DCHECK(client_socket_factory_); - DCHECK_GT(read_buf_size, 0); - DCHECK_GT(write_buf_size, 0); -} - -ChromeAsyncSocket::~ChromeAsyncSocket() {} - -ChromeAsyncSocket::State ChromeAsyncSocket::state() { - return state_; -} - -ChromeAsyncSocket::Error ChromeAsyncSocket::error() { - return error_; -} - -int ChromeAsyncSocket::GetError() { - return net_error_; -} - -bool ChromeAsyncSocket::IsOpen() const { - return (state_ == STATE_OPEN) || (state_ == STATE_TLS_OPEN); -} - -void ChromeAsyncSocket::DoNonNetError(Error error) { - DCHECK_NE(error, ERROR_NONE); - DCHECK_NE(error, ERROR_WINSOCK); - error_ = error; - net_error_ = net::OK; -} - -void ChromeAsyncSocket::DoNetError(net::Error net_error) { - error_ = ERROR_WINSOCK; - net_error_ = net_error; -} - -void ChromeAsyncSocket::DoNetErrorFromStatus(int status) { - DCHECK_LT(status, net::OK); - DoNetError(static_cast<net::Error>(status)); -} - -namespace { - -net::AddressList SocketAddressToAddressList( - const talk_base::SocketAddress& address) { - DCHECK_NE(address.ip(), 0); - // Use malloc() as net::AddressList uses free(). - addrinfo* ai = static_cast<addrinfo*>(std::malloc(sizeof *ai)); - memset(ai, 0, sizeof *ai); - ai->ai_family = AF_INET; - ai->ai_socktype = SOCK_STREAM; - ai->ai_addrlen = sizeof(sockaddr_in); - - sockaddr_in* addr = static_cast<sockaddr_in*>(std::malloc(sizeof *addr)); - memset(addr, 0, sizeof *addr); - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = htonl(address.ip()); - addr->sin_port = htons(address.port()); - ai->ai_addr = reinterpret_cast<sockaddr*>(addr); - - net::AddressList address_list; - address_list.Adopt(ai); - return address_list; -} - -} // namespace - -// STATE_CLOSED -> STATE_CONNECTING - -bool ChromeAsyncSocket::Connect(const talk_base::SocketAddress& address) { - if (state_ != STATE_CLOSED) { - LOG(DFATAL) << "Connect() called on non-closed socket"; - DoNonNetError(ERROR_WRONGSTATE); - return false; - } - if (address.ip() == 0) { - DoNonNetError(ERROR_DNS); - return false; - } - - DCHECK_EQ(state_, buzz::AsyncSocket::STATE_CLOSED); - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(write_state_, IDLE); - - state_ = STATE_CONNECTING; - - DCHECK(scoped_runnable_method_factory_.empty()); - scoped_runnable_method_factory_.RevokeAll(); - - net::AddressList address_list = SocketAddressToAddressList(address); - transport_socket_.reset( - client_socket_factory_-> - CreateTCPClientSocket(address_list, bound_net_log_.net_log())); - int status = transport_socket_->Connect(&connect_callback_); - if (status != net::ERR_IO_PENDING) { - // We defer execution of ProcessConnectDone instead of calling it - // directly here as the caller may not expect an error/close to - // happen here. This is okay, as from the caller's point of view, - // the connect always happens asynchronously. - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - scoped_runnable_method_factory_.NewRunnableMethod( - &ChromeAsyncSocket::ProcessConnectDone, status)); - } - return true; -} - -// STATE_CONNECTING -> STATE_OPEN -// read_state_ == IDLE -> read_state_ == POSTED (via PostDoRead()) - -void ChromeAsyncSocket::ProcessConnectDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(write_state_, IDLE); - DCHECK_EQ(state_, STATE_CONNECTING); - if (status != net::OK) { - DoNetErrorFromStatus(status); - DoClose(); - return; - } - state_ = STATE_OPEN; - PostDoRead(); - // Write buffer should be empty. - DCHECK_EQ(write_end_, 0); - SignalConnected(); -} - -// read_state_ == IDLE -> read_state_ == POSTED - -void ChromeAsyncSocket::PostDoRead() { - DCHECK(IsOpen()); - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(read_start_, 0); - DCHECK_EQ(read_end_, 0); - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - scoped_runnable_method_factory_.NewRunnableMethod( - &ChromeAsyncSocket::DoRead)); - read_state_ = POSTED; -} - -// read_state_ == POSTED -> read_state_ == PENDING - -void ChromeAsyncSocket::DoRead() { - DCHECK(IsOpen()); - DCHECK_EQ(read_state_, POSTED); - DCHECK_EQ(read_start_, 0); - DCHECK_EQ(read_end_, 0); - // Once we call Read(), we cannot call StartTls() until the read - // finishes. This is okay, as StartTls() is called only from a read - // handler (i.e., after a read finishes and before another read is - // done). - int status = - transport_socket_->Read( - read_buf_.get(), read_buf_->size(), &read_callback_); - read_state_ = PENDING; - if (status != net::ERR_IO_PENDING) { - ProcessReadDone(status); - } -} - -// read_state_ == PENDING -> read_state_ == IDLE - -void ChromeAsyncSocket::ProcessReadDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK(IsOpen()); - DCHECK_EQ(read_state_, PENDING); - DCHECK_EQ(read_start_, 0); - DCHECK_EQ(read_end_, 0); - read_state_ = IDLE; - if (status > 0) { - read_end_ = status; - SignalRead(); - } else if (status == 0) { - // Other side closed the connection. - error_ = ERROR_NONE; - net_error_ = net::OK; - DoClose(); - } else { // status < 0 - DoNetErrorFromStatus(status); - DoClose(); - } -} - -// (maybe) read_state_ == IDLE -> read_state_ == POSTED (via -// PostDoRead()) - -bool ChromeAsyncSocket::Read(char* data, size_t len, size_t* len_read) { - if (!IsOpen() && (state_ != STATE_TLS_CONNECTING)) { - // Read() may be called on a closed socket if a previous read - // causes a socket close (e.g., client sends wrong password and - // server terminates connection). - // - // TODO(akalin): Fix handling of this on the libjingle side. - if (state_ != STATE_CLOSED) { - LOG(DFATAL) << "Read() called on non-open non-tls-connecting socket"; - } - DoNonNetError(ERROR_WRONGSTATE); - return false; - } - DCHECK_LE(read_start_, read_end_); - if ((state_ == STATE_TLS_CONNECTING) || read_end_ == 0) { - if (state_ == STATE_TLS_CONNECTING) { - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(read_end_, 0); - } else { - DCHECK_NE(read_state_, IDLE); - } - *len_read = 0; - return true; - } - DCHECK_EQ(read_state_, IDLE); - *len_read = std::min(len, read_end_ - read_start_); - DCHECK_GT(*len_read, 0); - std::memcpy(data, read_buf_->data() + read_start_, *len_read); - read_start_ += *len_read; - if (read_start_ == read_end_) { - read_start_ = 0; - read_end_ = 0; - // We defer execution of DoRead() here for similar reasons as - // ProcessConnectDone(). - PostDoRead(); - } - return true; -} - -// (maybe) write_state_ == IDLE -> write_state_ == POSTED (via -// PostDoWrite()) - -bool ChromeAsyncSocket::Write(const char* data, size_t len) { - if (!IsOpen() && (state_ != STATE_TLS_CONNECTING)) { - LOG(DFATAL) << "Write() called on non-open non-tls-connecting socket"; - DoNonNetError(ERROR_WRONGSTATE); - return false; - } - // TODO(akalin): Avoid this check by modifying the interface to have - // a "ready for writing" signal. - if ((write_buf_->size() - write_end_) < len) { - LOG(DFATAL) << "queueing " << len << " bytes would exceed the " - << "max write buffer size = " << write_buf_->size() - << " by " << (len - write_buf_->size()) << " bytes"; - DoNetError(net::ERR_INSUFFICIENT_RESOURCES); - return false; - } - std::memcpy(write_buf_->data() + write_end_, data, len); - write_end_ += len; - // If we're TLS-connecting, the write buffer will get flushed once - // the TLS-connect finishes. Otherwise, start writing if we're not - // already writing and we have something to write. - if ((state_ != STATE_TLS_CONNECTING) && - (write_state_ == IDLE) && (write_end_ > 0)) { - // We defer execution of DoWrite() here for similar reasons as - // ProcessConnectDone(). - PostDoWrite(); - } - return true; -} - -// write_state_ == IDLE -> write_state_ == POSTED - -void ChromeAsyncSocket::PostDoWrite() { - DCHECK(IsOpen()); - DCHECK_EQ(write_state_, IDLE); - DCHECK_GT(write_end_, 0); - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - scoped_runnable_method_factory_.NewRunnableMethod( - &ChromeAsyncSocket::DoWrite)); - write_state_ = POSTED; -} - -// write_state_ == POSTED -> write_state_ == PENDING - -void ChromeAsyncSocket::DoWrite() { - DCHECK(IsOpen()); - DCHECK_EQ(write_state_, POSTED); - DCHECK_GT(write_end_, 0); - // Once we call Write(), we cannot call StartTls() until the write - // finishes. This is okay, as StartTls() is called only after we - // have received a reply to a message we sent to the server and - // before we send the next message. - int status = - transport_socket_->Write( - write_buf_.get(), write_end_, &write_callback_); - write_state_ = PENDING; - if (status != net::ERR_IO_PENDING) { - ProcessWriteDone(status); - } -} - -// write_state_ == PENDING -> write_state_ == IDLE or POSTED (the -// latter via PostDoWrite()) - -void ChromeAsyncSocket::ProcessWriteDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK(IsOpen()); - DCHECK_EQ(write_state_, PENDING); - DCHECK_GT(write_end_, 0); - write_state_ = IDLE; - if (status < net::OK) { - DoNetErrorFromStatus(status); - DoClose(); - return; - } - if (status > write_end_) { - LOG(DFATAL) << "bytes read = " << status - << " exceeds bytes requested = " << write_end_; - DoNetError(net::ERR_UNEXPECTED); - DoClose(); - return; - } - // TODO(akalin): Figure out a better way to do this; perhaps a queue - // of DrainableIOBuffers. This'll also allow us to not have an - // artificial buffer size limit. - std::memmove(write_buf_->data(), - write_buf_->data() + status, - write_end_ - status); - write_end_ -= status; - if (write_end_ > 0) { - PostDoWrite(); - } -} - -// * -> STATE_CLOSED - -bool ChromeAsyncSocket::Close() { - DoClose(); - return true; -} - -// (not STATE_CLOSED) -> STATE_CLOSED - -void ChromeAsyncSocket::DoClose() { - scoped_runnable_method_factory_.RevokeAll(); - if (transport_socket_.get()) { - transport_socket_->Disconnect(); - } - transport_socket_.reset(); - read_state_ = IDLE; - read_start_ = 0; - read_end_ = 0; - write_state_ = IDLE; - write_end_ = 0; - if (state_ != STATE_CLOSED) { - state_ = STATE_CLOSED; - SignalClosed(); - } - // Reset error variables after SignalClosed() so slots connected - // to it can read it. - error_ = ERROR_NONE; - net_error_ = net::OK; -} - -// STATE_OPEN -> STATE_TLS_CONNECTING - -bool ChromeAsyncSocket::StartTls(const std::string& domain_name) { - if ((state_ != STATE_OPEN) || (read_state_ == PENDING) || - (write_state_ != IDLE)) { - LOG(DFATAL) << "StartTls() called in wrong state"; - DoNonNetError(ERROR_WRONGSTATE); - return false; - } - - state_ = STATE_TLS_CONNECTING; - read_state_ = IDLE; - read_start_ = 0; - read_end_ = 0; - DCHECK_EQ(write_end_, 0); - - // Clear out any posted DoRead() tasks. - scoped_runnable_method_factory_.RevokeAll(); - - DCHECK(transport_socket_.get()); - transport_socket_.reset( - client_socket_factory_->CreateSSLClientSocket( - transport_socket_.release(), domain_name, ssl_config_)); - int status = transport_socket_->Connect(&ssl_connect_callback_); - if (status != net::ERR_IO_PENDING) { - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - scoped_runnable_method_factory_.NewRunnableMethod( - &ChromeAsyncSocket::ProcessSSLConnectDone, status)); - } - return true; -} - -// STATE_TLS_CONNECTING -> STATE_TLS_OPEN -// read_state_ == IDLE -> read_state_ == POSTED (via PostDoRead()) -// (maybe) write_state_ == IDLE -> write_state_ == POSTED (via -// PostDoWrite()) - -void ChromeAsyncSocket::ProcessSSLConnectDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK_EQ(state_, STATE_TLS_CONNECTING); - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(read_start_, 0); - DCHECK_EQ(read_end_, 0); - DCHECK_EQ(write_state_, IDLE); - if (status != net::OK) { - DoNetErrorFromStatus(status); - DoClose(); - return; - } - state_ = STATE_TLS_OPEN; - PostDoRead(); - if (write_end_ > 0) { - PostDoWrite(); - } - SignalSSLConnected(); -} - -} // namespace sync_tools diff --git a/chrome/browser/sync/tools/chrome_async_socket.h b/chrome/browser/sync/tools/chrome_async_socket.h deleted file mode 100644 index 63e1c3b..0000000 --- a/chrome/browser/sync/tools/chrome_async_socket.h +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// An implementation of buzz::AsyncSocket that uses Chrome sockets. - -#ifndef CHROME_BROWSER_SYNC_TOOLS_CHROME_ASYNC_SOCKET_H_ -#define CHROME_BROWSER_SYNC_TOOLS_CHROME_ASYNC_SOCKET_H_ - -#if !defined(FEATURE_ENABLE_SSL) -#error ChromeAsyncSocket expects FEATURE_ENABLE_SSL to be defined -#endif - -#include <string> -#include <vector> - -#include "base/basictypes.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "base/task.h" -#include "net/base/completion_callback.h" -#include "net/base/net_errors.h" -#include "net/base/net_log.h" -#include "net/base/ssl_config_service.h" -#include "talk/xmpp/asyncsocket.h" - -namespace net { -class ClientSocket; -class ClientSocketFactory; -class IOBufferWithSize; -} // namespace net - -namespace sync_tools { - -class ChromeAsyncSocket : public buzz::AsyncSocket { - public: - // Does not take ownership of |client_socket_factory| or |net_log|. - // |net_log| may be NULL. - ChromeAsyncSocket(net::ClientSocketFactory* client_socket_factory, - const net::SSLConfig& ssl_config, - size_t read_buf_size, - size_t write_buf_size, - net::NetLog* net_log); - - // Does not raise any signals. - virtual ~ChromeAsyncSocket(); - - // buzz::AsyncSocket implementation. - - // The current state (see buzz::AsyncSocket::State; all but - // STATE_CLOSING is used). - virtual State state(); - - // The last generated error. Errors are generated when the main - // functions below return false or when SignalClosed is raised due - // to an asynchronous error. - virtual Error error(); - - // GetError() (which is of type net::Error) != net::OK only when - // error() == ERROR_WINSOCK. - virtual int GetError(); - - // Tries to connect to the given address. - // - // If state() is not STATE_CLOSED, sets error to ERROR_WRONGSTATE - // and returns false. - // - // If |address| is not resolved, sets error to ERROR_DNS and returns - // false. - // - // Otherwise, starts the connection process and returns true. - // SignalConnected will be raised when the connection is successful; - // otherwise, SignalClosed will be raised with a net error set. - virtual bool Connect(const talk_base::SocketAddress& address); - - // Tries to read at most |len| bytes into |data|. - // - // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or - // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false. - // - // Otherwise, fills in |len_read| with the number of bytes read and - // returns true. If this is called when state() is - // STATE_TLS_CONNECTING, reads 0 bytes. (We have to handle this - // case because StartTls() is called during a slot connected to - // SignalRead after parsing the final non-TLS reply from the server - // [see XmppClient::Private::OnSocketRead()].) - virtual bool Read(char* data, size_t len, size_t* len_read); - - // Queues up |len| bytes of |data| for writing. - // - // If state() is not STATE_TLS_CONNECTING, STATE_OPEN, or - // STATE_TLS_OPEN, sets error to ERROR_WRONGSTATE and returns false. - // - // If the given data is too big for the internal write buffer, sets - // error to ERROR_WINSOCK/net::ERR_INSUFFICIENT_RESOURCES and - // returns false. - // - // Otherwise, queues up the data and returns true. If this is - // called when state() == STATE_TLS_CONNECTING, the data is will be - // sent only after the TLS connection succeeds. (See StartTls() - // below for why this happens.) - // - // Note that there's no guarantee that the data will actually be - // sent; however, it is guaranteed that the any data sent will be - // sent in FIFO order. - virtual bool Write(const char* data, size_t len); - - // If the socket is not already closed, closes the socket and raises - // SignalClosed. Always returns true. - virtual bool Close(); - - // Tries to change to a TLS connection with the given domain name. - // - // If state() is not STATE_OPEN or there are pending reads or - // writes, sets error to ERROR_WRONGSTATE and returns false. (In - // practice, this means that StartTls() can only be called from a - // slot connected to SignalRead.) - // - // Otherwise, starts the TLS connection process and returns true. - // SignalSSLConnected will be raised when the connection is - // successful; otherwise, SignalClosed will be raised with a net - // error set. - virtual bool StartTls(const std::string& domain_name); - - // Signal behavior: - // - // SignalConnected: raised whenever the connect initiated by a call - // to Connect() is complete. - // - // SignalSSLConnected: raised whenever the connect initiated by a - // call to StartTls() is complete. Not actually used by - // XmppClient. (It just assumes that if SignalRead is raised after a - // call to StartTls(), the connection has been successfully - // upgraded.) - // - // SignalClosed: raised whenever the socket is closed, either due to - // an asynchronous error, the other side closing the connection, or - // when Close() is called. - // - // SignalRead: raised whenever the next call to Read() will succeed - // with a non-zero |len_read| (assuming nothing else happens in the - // meantime). - // - // SignalError: not used. - - private: - enum AsyncIOState { - // An I/O op is not in progress. - IDLE, - // A function has been posted to do the I/O. - POSTED, - // An async I/O operation is pending. - PENDING, - }; - - bool IsOpen() const; - - // Error functions. - void DoNonNetError(Error error); - void DoNetError(net::Error net_error); - void DoNetErrorFromStatus(int status); - - // Connection functions. - void ProcessConnectDone(int status); - - // Read loop functions. - void PostDoRead(); - void DoRead(); - void ProcessReadDone(int status); - - // Write loop functions. - void PostDoWrite(); - void DoWrite(); - void ProcessWriteDone(int status); - - // SSL/TLS connection functions. - void ProcessSSLConnectDone(int status); - - // Close functions. - void DoClose(); - - // Callbacks passed to |transport_socket_|. - net::CompletionCallbackImpl<ChromeAsyncSocket> connect_callback_; - net::CompletionCallbackImpl<ChromeAsyncSocket> read_callback_; - net::CompletionCallbackImpl<ChromeAsyncSocket> write_callback_; - net::CompletionCallbackImpl<ChromeAsyncSocket> ssl_connect_callback_; - - // Weak pointer. - net::ClientSocketFactory* const client_socket_factory_; - const net::SSLConfig ssl_config_; - net::BoundNetLog bound_net_log_; - - // buzz::AsyncSocket state. - buzz::AsyncSocket::State state_; - buzz::AsyncSocket::Error error_; - net::Error net_error_; - - // Used by read/write loops. - ScopedRunnableMethodFactory<ChromeAsyncSocket> - scoped_runnable_method_factory_; - - // NULL iff state() == STATE_CLOSED. - // - // TODO(akalin): Use ClientSocketPool. - scoped_ptr<net::ClientSocket> transport_socket_; - - // State for the read loop. |read_start_| <= |read_end_| <= - // |read_buf_->size()|. There's a read in flight (i.e., - // |read_state_| != IDLE) iff |read_end_| == 0. - AsyncIOState read_state_; - scoped_refptr<net::IOBufferWithSize> read_buf_; - size_t read_start_, read_end_; - - // State for the write loop. |write_end_| <= |write_buf_->size()|. - // There's a write in flight (i.e., |write_state_| != IDLE) iff - // |write_end_| > 0. - AsyncIOState write_state_; - scoped_refptr<net::IOBufferWithSize> write_buf_; - size_t write_end_; - - DISALLOW_COPY_AND_ASSIGN(ChromeAsyncSocket); -}; - -} // namespace sync_tools - -#endif // CHROME_BROWSER_SYNC_TOOLS_CHROME_ASYNC_SOCKET_H_ diff --git a/chrome/browser/sync/tools/chrome_async_socket_unittest.cc b/chrome/browser/sync/tools/chrome_async_socket_unittest.cc deleted file mode 100644 index bf33ea5..0000000 --- a/chrome/browser/sync/tools/chrome_async_socket_unittest.cc +++ /dev/null @@ -1,1015 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/sync/tools/chrome_async_socket.h" - -#include <deque> -#include <string> - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "net/base/ssl_config_service.h" -#include "net/base/capturing_net_log.h" -#include "net/base/net_errors.h" -#include "net/socket/socket_test_util.h" -#include "talk/base/sigslot.h" -#include "talk/base/socketaddress.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_tools { - -namespace { - -// Data provider that handles reads/writes for ChromeAsyncSocket. -class AsyncSocketDataProvider : public net::SocketDataProvider { - public: - AsyncSocketDataProvider() : has_pending_read_(false) {} - - virtual ~AsyncSocketDataProvider() { - EXPECT_TRUE(writes_.empty()); - EXPECT_TRUE(reads_.empty()); - } - - // If there's no read, sets the "has pending read" flag. Otherwise, - // pops the next read. - virtual net::MockRead GetNextRead() { - if (reads_.empty()) { - DCHECK(!has_pending_read_); - has_pending_read_ = true; - const net::MockRead pending_read(false, net::ERR_IO_PENDING); - return pending_read; - } - net::MockRead mock_read = reads_.front(); - reads_.pop_front(); - return mock_read; - } - - // Simply pops the next write and, if applicable, compares it to - // |data|. - virtual net::MockWriteResult OnWrite(const std::string& data) { - DCHECK(!writes_.empty()); - net::MockWrite mock_write = writes_.front(); - writes_.pop_front(); - if (mock_write.result != net::OK) { - return net::MockWriteResult(mock_write.async, mock_write.result); - } - std::string expected_data(mock_write.data, mock_write.data_len); - EXPECT_EQ(expected_data, data); - if (expected_data != data) { - return net::MockWriteResult(false, net::ERR_UNEXPECTED); - } - return net::MockWriteResult(mock_write.async, data.size()); - } - - // We ignore resets so we can pre-load the socket data provider with - // read/write events. - virtual void Reset() {} - - // If there is a pending read, completes it with the given read. - // Otherwise, queues up the given read. - void AddRead(const net::MockRead& mock_read) { - DCHECK_NE(mock_read.result, net::ERR_IO_PENDING); - if (has_pending_read_) { - socket()->OnReadComplete(mock_read); - has_pending_read_ = false; - return; - } - reads_.push_back(mock_read); - } - - // Simply queues up the given write. - void AddWrite(const net::MockWrite& mock_write) { - writes_.push_back(mock_write); - } - - private: - std::deque<net::MockRead> reads_; - bool has_pending_read_; - - std::deque<net::MockWrite> writes_; - - DISALLOW_COPY_AND_ASSIGN(AsyncSocketDataProvider); -}; - -class ChromeAsyncSocketTest - : public testing::Test, - public sigslot::has_slots<> { - protected: - ChromeAsyncSocketTest() - : ssl_socket_data_provider_(true, net::OK), - capturing_net_log_(net::CapturingNetLog::kUnbounded), - chrome_async_socket_(&mock_client_socket_factory_, - ssl_config_, 14, 20, &capturing_net_log_), - addr_(0xaabbccdd, 35) {} - - virtual ~ChromeAsyncSocketTest() {} - - virtual void SetUp() { - mock_client_socket_factory_.AddSocketDataProvider( - &async_socket_data_provider_); - mock_client_socket_factory_.AddSSLSocketDataProvider( - &ssl_socket_data_provider_); - - chrome_async_socket_.SignalConnected.connect( - this, &ChromeAsyncSocketTest::OnConnect); - chrome_async_socket_.SignalSSLConnected.connect( - this, &ChromeAsyncSocketTest::OnSSLConnect); - chrome_async_socket_.SignalClosed.connect( - this, &ChromeAsyncSocketTest::OnClose); - chrome_async_socket_.SignalRead.connect( - this, &ChromeAsyncSocketTest::OnRead); - chrome_async_socket_.SignalError.connect( - this, &ChromeAsyncSocketTest::OnError); - } - - virtual void TearDown() { - // Run any tasks that we forgot to pump. - message_loop_.RunAllPending(); - ExpectClosed(); - ExpectNoSignal(); - chrome_async_socket_.SignalConnected.disconnect(this); - chrome_async_socket_.SignalSSLConnected.disconnect(this); - chrome_async_socket_.SignalClosed.disconnect(this); - chrome_async_socket_.SignalRead.disconnect(this); - chrome_async_socket_.SignalError.disconnect(this); - } - - enum Signal { - SIGNAL_CONNECT, - SIGNAL_SSL_CONNECT, - SIGNAL_CLOSE, - SIGNAL_READ, - SIGNAL_ERROR, - }; - - // Helper struct that records the state at the time of a signal. - - struct SignalSocketState { - SignalSocketState() - : signal(SIGNAL_ERROR), - state(ChromeAsyncSocket::STATE_CLOSED), - error(ChromeAsyncSocket::ERROR_NONE), - net_error(net::OK) {} - - SignalSocketState( - Signal signal, - ChromeAsyncSocket::State state, - ChromeAsyncSocket::Error error, - net::Error net_error) - : signal(signal), - state(state), - error(error), - net_error(net_error) {} - - bool IsEqual(const SignalSocketState& other) const { - return - (signal == other.signal) && - (state == other.state) && - (error == other.error) && - (net_error == other.net_error); - } - - static SignalSocketState FromAsyncSocket( - Signal signal, - buzz::AsyncSocket* async_socket) { - return SignalSocketState(signal, - async_socket->state(), - async_socket->error(), - static_cast<net::Error>( - async_socket->GetError())); - } - - static SignalSocketState NoError( - Signal signal, buzz::AsyncSocket::State state) { - return SignalSocketState(signal, state, - buzz::AsyncSocket::ERROR_NONE, - net::OK); - } - - Signal signal; - ChromeAsyncSocket::State state; - ChromeAsyncSocket::Error error; - net::Error net_error; - }; - - void CaptureSocketState(Signal signal) { - signal_socket_states_.push_back( - SignalSocketState::FromAsyncSocket(signal, &chrome_async_socket_)); - } - - void OnConnect() { - CaptureSocketState(SIGNAL_CONNECT); - } - - void OnSSLConnect() { - CaptureSocketState(SIGNAL_SSL_CONNECT); - } - - void OnClose() { - CaptureSocketState(SIGNAL_CLOSE); - } - - void OnRead() { - CaptureSocketState(SIGNAL_READ); - } - - void OnError() { - ADD_FAILURE(); - } - - // State expect functions. - - void ExpectState(ChromeAsyncSocket::State state, - ChromeAsyncSocket::Error error, - net::Error net_error) { - EXPECT_EQ(state, chrome_async_socket_.state()); - EXPECT_EQ(error, chrome_async_socket_.error()); - EXPECT_EQ(net_error, chrome_async_socket_.GetError()); - } - - void ExpectNonErrorState(ChromeAsyncSocket::State state) { - ExpectState(state, ChromeAsyncSocket::ERROR_NONE, net::OK); - } - - void ExpectErrorState(ChromeAsyncSocket::State state, - ChromeAsyncSocket::Error error) { - ExpectState(state, error, net::OK); - } - - void ExpectClosed() { - ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); - } - - // Signal expect functions. - - void ExpectNoSignal() { - if (!signal_socket_states_.empty()) { - ADD_FAILURE() << signal_socket_states_.front().signal; - } - } - - void ExpectSignalSocketState( - SignalSocketState expected_signal_socket_state) { - if (signal_socket_states_.empty()) { - ADD_FAILURE() << expected_signal_socket_state.signal; - return; - } - EXPECT_TRUE(expected_signal_socket_state.IsEqual( - signal_socket_states_.front())) - << signal_socket_states_.front().signal; - signal_socket_states_.pop_front(); - } - - void ExpectReadSignal() { - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_READ, ChromeAsyncSocket::STATE_OPEN)); - } - - void ExpectSSLConnectSignal() { - ExpectSignalSocketState( - SignalSocketState::NoError(SIGNAL_SSL_CONNECT, - ChromeAsyncSocket::STATE_TLS_OPEN)); - } - - void ExpectSSLReadSignal() { - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_READ, ChromeAsyncSocket::STATE_TLS_OPEN)); - } - - // Open/close utility functions. - - void DoOpenClosed() { - ExpectClosed(); - async_socket_data_provider_.set_connect_data( - net::MockConnect(false, net::OK)); - EXPECT_TRUE(chrome_async_socket_.Connect(addr_)); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); - - message_loop_.RunAllPending(); - // We may not necessarily be open; may have been other events - // queued up. - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN)); - } - - void DoCloseOpened(SignalSocketState expected_signal_socket_state) { - // We may be in an error state, so just compare state(). - EXPECT_EQ(ChromeAsyncSocket::STATE_OPEN, chrome_async_socket_.state()); - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectSignalSocketState(expected_signal_socket_state); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); - } - - void DoCloseOpenedNoError() { - DoCloseOpened( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); - } - - void DoSSLOpenClosed() { - const char kDummyData[] = "dummy_data"; - async_socket_data_provider_.AddRead(net::MockRead(kDummyData)); - DoOpenClosed(); - ExpectReadSignal(); - EXPECT_EQ(kDummyData, DrainRead(1)); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - message_loop_.RunAllPending(); - ExpectSSLConnectSignal(); - ExpectNoSignal(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); - } - - void DoSSLCloseOpened(SignalSocketState expected_signal_socket_state) { - // We may be in an error state, so just compare state(). - EXPECT_EQ(ChromeAsyncSocket::STATE_TLS_OPEN, - chrome_async_socket_.state()); - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectSignalSocketState(expected_signal_socket_state); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); - } - - void DoSSLCloseOpenedNoError() { - DoSSLCloseOpened( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); - } - - // Read utility fucntions. - - std::string DrainRead(size_t buf_size) { - std::string read; - scoped_array<char> buf(new char[buf_size]); - size_t len_read; - while (true) { - bool success = - chrome_async_socket_.Read(buf.get(), buf_size, &len_read); - if (!success) { - ADD_FAILURE(); - break; - } - if (len_read == 0) { - break; - } - read.append(buf.get(), len_read); - } - return read; - } - - // ChromeAsyncSocket expects a message loop. - MessageLoop message_loop_; - - net::MockClientSocketFactory mock_client_socket_factory_; - AsyncSocketDataProvider async_socket_data_provider_; - net::SSLSocketDataProvider ssl_socket_data_provider_; - - net::CapturingNetLog capturing_net_log_; - net::SSLConfig ssl_config_; - ChromeAsyncSocket chrome_async_socket_; - std::deque<SignalSocketState> signal_socket_states_; - const talk_base::SocketAddress addr_; - - private: - DISALLOW_COPY_AND_ASSIGN(ChromeAsyncSocketTest); -}; - -TEST_F(ChromeAsyncSocketTest, InitialState) { - ExpectClosed(); - ExpectNoSignal(); -} - -TEST_F(ChromeAsyncSocketTest, EmptyClose) { - ExpectClosed(); - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); -} - -TEST_F(ChromeAsyncSocketTest, ImmediateConnectAndClose) { - DoOpenClosed(); - - ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN); - - DoCloseOpenedNoError(); -} - -// After this, no need to test immediate successful connect and -// Close() so thoroughly. - -TEST_F(ChromeAsyncSocketTest, DoubleClose) { - DoOpenClosed(); - - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); - - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); -} - -TEST_F(ChromeAsyncSocketTest, UnresolvedConnect) { - const talk_base::SocketAddress unresolved_addr(0, 0); - EXPECT_FALSE(chrome_async_socket_.Connect(unresolved_addr)); - ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_DNS); - - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); -} - -TEST_F(ChromeAsyncSocketTest, DoubleConnect) { - EXPECT_DEBUG_DEATH({ - DoOpenClosed(); - - EXPECT_FALSE(chrome_async_socket_.Connect(addr_)); - ExpectErrorState(ChromeAsyncSocket::STATE_OPEN, - ChromeAsyncSocket::ERROR_WRONGSTATE); - - DoCloseOpened( - SignalSocketState(SIGNAL_CLOSE, - ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE, - net::OK)); - }, "non-closed socket"); -} - -TEST_F(ChromeAsyncSocketTest, ImmediateConnectCloseBeforeRead) { - DoOpenClosed(); - - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); - - message_loop_.RunAllPending(); -} - -TEST_F(ChromeAsyncSocketTest, HangingConnect) { - EXPECT_TRUE(chrome_async_socket_.Connect(addr_)); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); - ExpectNoSignal(); - - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); -} - -TEST_F(ChromeAsyncSocketTest, PendingConnect) { - async_socket_data_provider_.set_connect_data( - net::MockConnect(true, net::OK)); - EXPECT_TRUE(chrome_async_socket_.Connect(addr_)); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); - ExpectNoSignal(); - - message_loop_.RunAllPending(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN); - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN)); - ExpectNoSignal(); - - message_loop_.RunAllPending(); - - DoCloseOpenedNoError(); -} - -// After this no need to test successful pending connect so -// thoroughly. - -TEST_F(ChromeAsyncSocketTest, PendingConnectCloseBeforeRead) { - async_socket_data_provider_.set_connect_data( - net::MockConnect(true, net::OK)); - EXPECT_TRUE(chrome_async_socket_.Connect(addr_)); - - message_loop_.RunAllPending(); - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN)); - - DoCloseOpenedNoError(); - - message_loop_.RunAllPending(); -} - -TEST_F(ChromeAsyncSocketTest, PendingConnectError) { - async_socket_data_provider_.set_connect_data( - net::MockConnect(true, net::ERR_TIMED_OUT)); - EXPECT_TRUE(chrome_async_socket_.Connect(addr_)); - - message_loop_.RunAllPending(); - - ExpectSignalSocketState( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); -} - -// After this we can assume Connect() and Close() work as expected. - -TEST_F(ChromeAsyncSocketTest, EmptyRead) { - DoOpenClosed(); - - char buf[4096]; - size_t len_read = 10000; - EXPECT_TRUE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read)); - EXPECT_EQ(0, len_read); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, WrongRead) { - EXPECT_DEBUG_DEATH({ - async_socket_data_provider_.set_connect_data( - net::MockConnect(true, net::OK)); - EXPECT_TRUE(chrome_async_socket_.Connect(addr_)); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); - ExpectNoSignal(); - - char buf[4096]; - size_t len_read; - EXPECT_FALSE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read)); - ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE); - EXPECT_TRUE(chrome_async_socket_.Close()); - }, "non-open"); -} - -TEST_F(ChromeAsyncSocketTest, WrongReadClosed) { - char buf[4096]; - size_t len_read; - EXPECT_FALSE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read)); - ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE); - EXPECT_TRUE(chrome_async_socket_.Close()); -} - -const char kReadData[] = "mydatatoread"; - -TEST_F(ChromeAsyncSocketTest, Read) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - - ExpectReadSignal(); - ExpectNoSignal(); - - EXPECT_EQ(kReadData, DrainRead(1)); - - message_loop_.RunAllPending(); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, ReadTwice) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - - ExpectReadSignal(); - ExpectNoSignal(); - - EXPECT_EQ(kReadData, DrainRead(1)); - - message_loop_.RunAllPending(); - - const char kReadData2[] = "mydatatoread2"; - async_socket_data_provider_.AddRead(net::MockRead(kReadData2)); - - ExpectReadSignal(); - ExpectNoSignal(); - - EXPECT_EQ(kReadData2, DrainRead(1)); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, ReadError) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - - ExpectReadSignal(); - ExpectNoSignal(); - - EXPECT_EQ(kReadData, DrainRead(1)); - - message_loop_.RunAllPending(); - - async_socket_data_provider_.AddRead( - net::MockRead(false, net::ERR_TIMED_OUT)); - - ExpectSignalSocketState( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); -} - -TEST_F(ChromeAsyncSocketTest, ReadEmpty) { - async_socket_data_provider_.AddRead(net::MockRead("")); - DoOpenClosed(); - - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); -} - -TEST_F(ChromeAsyncSocketTest, PendingRead) { - DoOpenClosed(); - - ExpectNoSignal(); - - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_READ, ChromeAsyncSocket::STATE_OPEN)); - ExpectNoSignal(); - - EXPECT_EQ(kReadData, DrainRead(1)); - - message_loop_.RunAllPending(); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, PendingEmptyRead) { - DoOpenClosed(); - - ExpectNoSignal(); - - async_socket_data_provider_.AddRead(net::MockRead("")); - - ExpectSignalSocketState( - SignalSocketState::NoError( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); -} - -TEST_F(ChromeAsyncSocketTest, PendingReadError) { - DoOpenClosed(); - - ExpectNoSignal(); - - async_socket_data_provider_.AddRead( - net::MockRead(true, net::ERR_TIMED_OUT)); - - ExpectSignalSocketState( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); -} - -// After this we can assume non-SSL Read() works as expected. - -TEST_F(ChromeAsyncSocketTest, WrongWrite) { - EXPECT_DEBUG_DEATH({ - std::string data("foo"); - EXPECT_FALSE(chrome_async_socket_.Write(data.data(), data.size())); - ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE); - EXPECT_TRUE(chrome_async_socket_.Close()); - }, "non-open"); -} - -const char kWriteData[] = "mydatatowrite"; - -TEST_F(ChromeAsyncSocketTest, SyncWrite) { - async_socket_data_provider_.AddWrite( - net::MockWrite(false, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(false, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(false, kWriteData + 8, arraysize(kWriteData) - 8)); - DoOpenClosed(); - - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8, - arraysize(kWriteData) - 8)); - message_loop_.RunAllPending(); - - ExpectNoSignal(); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, AsyncWrite) { - DoOpenClosed(); - - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData + 8, arraysize(kWriteData) - 8)); - - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8, - arraysize(kWriteData) - 8)); - message_loop_.RunAllPending(); - - ExpectNoSignal(); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, AsyncWriteError) { - DoOpenClosed(); - - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(true, net::ERR_TIMED_OUT)); - - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8, - arraysize(kWriteData) - 8)); - message_loop_.RunAllPending(); - - ExpectSignalSocketState( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); -} - -TEST_F(ChromeAsyncSocketTest, LargeWrite) { - EXPECT_DEBUG_DEATH({ - DoOpenClosed(); - - std::string large_data(100, 'x'); - EXPECT_FALSE(chrome_async_socket_.Write(large_data.data(), - large_data.size())); - ExpectState(ChromeAsyncSocket::STATE_OPEN, - ChromeAsyncSocket::ERROR_WINSOCK, - net::ERR_INSUFFICIENT_RESOURCES); - DoCloseOpened( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, - net::ERR_INSUFFICIENT_RESOURCES)); - }, "exceed the max write buffer"); -} - -TEST_F(ChromeAsyncSocketTest, LargeAccumulatedWrite) { - EXPECT_DEBUG_DEATH({ - DoOpenClosed(); - - std::string data(15, 'x'); - EXPECT_TRUE(chrome_async_socket_.Write(data.data(), data.size())); - EXPECT_FALSE(chrome_async_socket_.Write(data.data(), data.size())); - ExpectState(ChromeAsyncSocket::STATE_OPEN, - ChromeAsyncSocket::ERROR_WINSOCK, - net::ERR_INSUFFICIENT_RESOURCES); - DoCloseOpened( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, - net::ERR_INSUFFICIENT_RESOURCES)); - }, "exceed the max write buffer"); -} - -// After this we can assume non-SSL I/O works as expected. - -TEST_F(ChromeAsyncSocketTest, HangingSSLConnect) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - ExpectReadSignal(); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - ExpectNoSignal(); - - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_CONNECTING); - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectSignalSocketState( - SignalSocketState::NoError(SIGNAL_CLOSE, - ChromeAsyncSocket::STATE_CLOSED)); - ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); -} - -TEST_F(ChromeAsyncSocketTest, ImmediateSSLConnect) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - ExpectReadSignal(); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - message_loop_.RunAllPending(); - ExpectSSLConnectSignal(); - ExpectNoSignal(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); - - DoSSLCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, DoubleSSLConnect) { - EXPECT_DEBUG_DEATH({ - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - ExpectReadSignal(); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - message_loop_.RunAllPending(); - ExpectSSLConnectSignal(); - ExpectNoSignal(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); - - EXPECT_FALSE(chrome_async_socket_.StartTls("fakedomain.com")); - - DoSSLCloseOpened( - SignalSocketState(SIGNAL_CLOSE, - ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE, - net::OK)); - }, "wrong state"); -} - -TEST_F(ChromeAsyncSocketTest, FailedSSLConnect) { - ssl_socket_data_provider_.connect = - net::MockConnect(true, net::ERR_CERT_COMMON_NAME_INVALID), - - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - ExpectReadSignal(); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - message_loop_.RunAllPending(); - ExpectSignalSocketState( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WINSOCK, - net::ERR_CERT_COMMON_NAME_INVALID)); - - EXPECT_TRUE(chrome_async_socket_.Close()); - ExpectClosed(); -} - -TEST_F(ChromeAsyncSocketTest, ReadDuringSSLConnecting) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - ExpectReadSignal(); - EXPECT_EQ(kReadData, DrainRead(1)); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - ExpectNoSignal(); - - // Shouldn't do anything. - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - - char buf[4096]; - size_t len_read = 10000; - EXPECT_TRUE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read)); - EXPECT_EQ(0, len_read); - - message_loop_.RunAllPending(); - ExpectSSLConnectSignal(); - ExpectSSLReadSignal(); - ExpectNoSignal(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); - - len_read = 10000; - EXPECT_TRUE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read)); - EXPECT_EQ(kReadData, std::string(buf, len_read)); - - DoSSLCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, WriteDuringSSLConnecting) { - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - DoOpenClosed(); - ExpectReadSignal(); - - EXPECT_TRUE(chrome_async_socket_.StartTls("fakedomain.com")); - ExpectNoSignal(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_CONNECTING); - - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData, 3)); - - // Shouldn't do anything. - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - - // TODO(akalin): Figure out how to test that the write happens - // *after* the SSL connect. - - message_loop_.RunAllPending(); - ExpectSSLConnectSignal(); - ExpectNoSignal(); - - message_loop_.RunAllPending(); - - DoSSLCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, SSLConnectDuringPendingRead) { - EXPECT_DEBUG_DEATH({ - DoOpenClosed(); - - EXPECT_FALSE(chrome_async_socket_.StartTls("fakedomain.com")); - - DoCloseOpened( - SignalSocketState(SIGNAL_CLOSE, - ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE, - net::OK)); - }, "wrong state"); -} - -TEST_F(ChromeAsyncSocketTest, SSLConnectDuringPostedWrite) { - EXPECT_DEBUG_DEATH({ - DoOpenClosed(); - - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData, 3)); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - - EXPECT_FALSE(chrome_async_socket_.StartTls("fakedomain.com")); - - message_loop_.RunAllPending(); - - DoCloseOpened( - SignalSocketState(SIGNAL_CLOSE, - ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE, - net::OK)); - }, "wrong state"); -} - -// After this we can assume SSL connect works as expected. - -TEST_F(ChromeAsyncSocketTest, SSLRead) { - DoSSLOpenClosed(); - async_socket_data_provider_.AddRead(net::MockRead(kReadData)); - message_loop_.RunAllPending(); - - ExpectSSLReadSignal(); - ExpectNoSignal(); - - EXPECT_EQ(kReadData, DrainRead(1)); - - message_loop_.RunAllPending(); - - DoSSLCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, SSLSyncWrite) { - async_socket_data_provider_.AddWrite( - net::MockWrite(false, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(false, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(false, kWriteData + 8, arraysize(kWriteData) - 8)); - DoSSLOpenClosed(); - - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8, - arraysize(kWriteData) - 8)); - message_loop_.RunAllPending(); - - ExpectNoSignal(); - - DoSSLCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, SSLAsyncWrite) { - DoSSLOpenClosed(); - - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(true, kWriteData + 8, arraysize(kWriteData) - 8)); - - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5)); - message_loop_.RunAllPending(); - EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8, - arraysize(kWriteData) - 8)); - message_loop_.RunAllPending(); - - ExpectNoSignal(); - - DoSSLCloseOpenedNoError(); -} - -} // namespace - -} // namespace sync_tools diff --git a/chrome/browser/sync/tools/sync_listen_notifications.cc b/chrome/browser/sync/tools/sync_listen_notifications.cc index d2c972a..69431e1 100644 --- a/chrome/browser/sync/tools/sync_listen_notifications.cc +++ b/chrome/browser/sync/tools/sync_listen_notifications.cc @@ -17,8 +17,8 @@ #include "chrome/browser/sync/notifier/chrome_invalidation_client.h" #include "chrome/browser/sync/notifier/chrome_system_resources.h" #include "chrome/browser/sync/sync_constants.h" -#include "chrome/browser/sync/tools/chrome_async_socket.h" #include "chrome/common/chrome_switches.h" +#include "jingle/notifier/base/chrome_async_socket.h" #include "jingle/notifier/base/task_pump.h" #include "jingle/notifier/communicator/xmpp_socket_adapter.h" #include "jingle/notifier/listener/listen_task.h" @@ -100,7 +100,7 @@ class XmppNotificationClient : public sigslot::has_slots<> { buzz::AsyncSocket* buzz_async_socket = use_chrome_async_socket ? static_cast<buzz::AsyncSocket*>( - new sync_tools::ChromeAsyncSocket( + new notifier::ChromeAsyncSocket( net::ClientSocketFactory::GetDefaultFactory(), ssl_config, 4096, 64 * 1024, NULL)) : static_cast<buzz::AsyncSocket*>( diff --git a/chrome/browser/sync/tools/sync_tools.gyp b/chrome/browser/sync/tools/sync_tools.gyp index 0205024..18d163c 100644 --- a/chrome/browser/sync/tools/sync_tools.gyp +++ b/chrome/browser/sync/tools/sync_tools.gyp @@ -5,22 +5,6 @@ { 'targets': [ { - 'target_name': 'chrome_async_socket', - 'type': '<(library)', - 'sources': [ - 'chrome_async_socket.cc', - 'chrome_async_socket.h', - ], - 'dependencies': [ - '<(DEPTH)/base/base.gyp:base', - '<(DEPTH)/net/net.gyp:net', - '<(DEPTH)/third_party/libjingle/libjingle.gyp:libjingle', - ], - 'export_dependent_settings': [ - '<(DEPTH)/third_party/libjingle/libjingle.gyp:libjingle', - ], - }, - { 'target_name': 'sync_listen_notifications', 'type': 'executable', 'sources': [ @@ -32,7 +16,6 @@ '<(DEPTH)/chrome/browser/sync/sync_constants.h', ], 'dependencies': [ - 'chrome_async_socket', '<(DEPTH)/base/base.gyp:base', '<(DEPTH)/chrome/chrome.gyp:common_constants', '<(DEPTH)/chrome/chrome.gyp:sync_notifier', @@ -40,35 +23,6 @@ '<(DEPTH)/third_party/libjingle/libjingle.gyp:libjingle', ], }, - { - 'target_name': 'chrome_async_socket_unit_tests', - 'type': 'executable', - 'sources': [ - # TODO(akalin): Write our own test suite and runner. - '<(DEPTH)/base/test/run_all_unittests.cc', - '<(DEPTH)/base/test/test_suite.h', - 'chrome_async_socket_unittest.cc', - ], - 'dependencies': [ - 'chrome_async_socket', - '<(DEPTH)/base/base.gyp:base', - '<(DEPTH)/net/net.gyp:net', - '<(DEPTH)/net/net.gyp:net_test_support', - '<(DEPTH)/testing/gtest.gyp:gtest', - ], - # TODO(akalin): Remove this once we have our own test suite and - # runner. - 'conditions': [ - ['OS == "linux" or OS == "freebsd" or OS == "openbsd" or OS == "solaris"', { - 'dependencies': [ - # Needed to handle the #include chain: - # base/test/test_suite.h - # gtk/gtk.h - '<(DEPTH)/build/linux/system.gyp:gtk', - ], - }], - ], - }, ], } |