diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-24 01:54:41 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-24 01:54:41 +0000 |
commit | 47a5122ed84875b8dea2fda4100d01dd9fa31483 (patch) | |
tree | e6538f26e92c685c37de4f8f861e229defa9f912 /jingle/notifier | |
parent | 129f2869aca4cdffb14f09c9bcc3d49f087b564d (diff) | |
download | chromium_src-47a5122ed84875b8dea2fda4100d01dd9fa31483.zip chromium_src-47a5122ed84875b8dea2fda4100d01dd9fa31483.tar.gz chromium_src-47a5122ed84875b8dea2fda4100d01dd9fa31483.tar.bz2 |
Move ChromeAsyncSocket to jingle/glue
ChromeAsyncSocket will be reused by chromoting for XMPP connections,
moving it to jingle/glue.
BUG=137140
Review URL: https://chromiumcodereview.appspot.com/10817013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148028 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'jingle/notifier')
-rw-r--r-- | jingle/notifier/base/chrome_async_socket.cc | 450 | ||||
-rw-r--r-- | jingle/notifier/base/chrome_async_socket.h | 213 | ||||
-rw-r--r-- | jingle/notifier/base/chrome_async_socket_unittest.cc | 1079 | ||||
-rw-r--r-- | jingle/notifier/base/fake_ssl_client_socket.cc | 353 | ||||
-rw-r--r-- | jingle/notifier/base/fake_ssl_client_socket.h | 114 | ||||
-rw-r--r-- | jingle/notifier/base/fake_ssl_client_socket_unittest.cc | 348 | ||||
-rw-r--r-- | jingle/notifier/base/proxy_resolving_client_socket.cc | 392 | ||||
-rw-r--r-- | jingle/notifier/base/proxy_resolving_client_socket.h | 106 | ||||
-rw-r--r-- | jingle/notifier/base/proxy_resolving_client_socket_unittest.cc | 117 | ||||
-rw-r--r-- | jingle/notifier/base/resolving_client_socket_factory.h | 36 | ||||
-rw-r--r-- | jingle/notifier/base/xmpp_client_socket_factory.cc | 56 | ||||
-rw-r--r-- | jingle/notifier/base/xmpp_client_socket_factory.h | 56 | ||||
-rw-r--r-- | jingle/notifier/base/xmpp_connection.cc | 12 |
13 files changed, 6 insertions, 3326 deletions
diff --git a/jingle/notifier/base/chrome_async_socket.cc b/jingle/notifier/base/chrome_async_socket.cc deleted file mode 100644 index ca2fde4..0000000 --- a/jingle/notifier/base/chrome_async_socket.cc +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/chrome_async_socket.h" - -#include <algorithm> -#include <cstring> -#include <cstdlib> - -#include "base/basictypes.h" -#include "base/bind.h" -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "jingle/notifier/base/resolving_client_socket_factory.h" -#include "net/base/address_list.h" -#include "net/base/host_port_pair.h" -#include "net/base/io_buffer.h" -#include "net/base/net_util.h" -#include "net/base/ssl_config_service.h" -#include "net/socket/client_socket_handle.h" -#include "net/socket/ssl_client_socket.h" -#include "net/socket/tcp_client_socket.h" -#include "talk/base/socketaddress.h" - -namespace notifier { - -ChromeAsyncSocket::ChromeAsyncSocket( - ResolvingClientSocketFactory* resolving_client_socket_factory, - size_t read_buf_size, - size_t write_buf_size) - : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), - resolving_client_socket_factory_(resolving_client_socket_factory), - state_(STATE_CLOSED), - error_(ERROR_NONE), - net_error_(net::OK), - read_state_(IDLE), - read_buf_(new net::IOBufferWithSize(read_buf_size)), - read_start_(0U), - read_end_(0U), - write_state_(IDLE), - write_buf_(new net::IOBufferWithSize(write_buf_size)), - write_end_(0U) { - DCHECK(resolving_client_socket_factory_.get()); - DCHECK_GT(read_buf_size, 0U); - DCHECK_GT(write_buf_size, 0U); -} - -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)); -} - -// 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.hostname().empty() || address.port() == 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(!weak_ptr_factory_.HasWeakPtrs()); - weak_ptr_factory_.InvalidateWeakPtrs(); - - net::HostPortPair dest_host_port_pair(address.hostname(), address.port()); - - transport_socket_.reset( - resolving_client_socket_factory_->CreateTransportClientSocket( - dest_host_port_pair)); - int status = transport_socket_->Connect( - base::Bind(&ChromeAsyncSocket::ProcessConnectDone, - weak_ptr_factory_.GetWeakPtr())); - 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, - base::Bind(&ChromeAsyncSocket::ProcessConnectDone, - weak_ptr_factory_.GetWeakPtr(), 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_, 0U); - SignalConnected(); -} - -// read_state_ == IDLE -> read_state_ == POSTED - -void ChromeAsyncSocket::PostDoRead() { - DCHECK(IsOpen()); - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(read_start_, 0U); - DCHECK_EQ(read_end_, 0U); - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - base::Bind(&ChromeAsyncSocket::DoRead, - weak_ptr_factory_.GetWeakPtr())); - read_state_ = POSTED; -} - -// read_state_ == POSTED -> read_state_ == PENDING - -void ChromeAsyncSocket::DoRead() { - DCHECK(IsOpen()); - DCHECK_EQ(read_state_, POSTED); - DCHECK_EQ(read_start_, 0U); - DCHECK_EQ(read_end_, 0U); - // 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(), - base::Bind(&ChromeAsyncSocket::ProcessReadDone, - weak_ptr_factory_.GetWeakPtr())); - 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_, 0U); - DCHECK_EQ(read_end_, 0U); - read_state_ = IDLE; - if (status > 0) { - read_end_ = static_cast<size_t>(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_ == 0U) { - if (state_ == STATE_TLS_CONNECTING) { - DCHECK_EQ(read_state_, IDLE); - DCHECK_EQ(read_end_, 0U); - } 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, 0U); - std::memcpy(data, read_buf_->data() + read_start_, *len_read); - read_start_ += *len_read; - if (read_start_ == read_end_) { - read_start_ = 0U; - read_end_ = 0U; - // 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 ((static_cast<size_t>(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_ > 0U)) { - // 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_, 0U); - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - base::Bind(&ChromeAsyncSocket::DoWrite, - weak_ptr_factory_.GetWeakPtr())); - write_state_ = POSTED; -} - -// write_state_ == POSTED -> write_state_ == PENDING - -void ChromeAsyncSocket::DoWrite() { - DCHECK(IsOpen()); - DCHECK_EQ(write_state_, POSTED); - DCHECK_GT(write_end_, 0U); - // 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_, - base::Bind(&ChromeAsyncSocket::ProcessWriteDone, - weak_ptr_factory_.GetWeakPtr())); - 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_, 0U); - write_state_ = IDLE; - if (status < net::OK) { - DoNetErrorFromStatus(status); - DoClose(); - return; - } - size_t written = static_cast<size_t>(status); - if (written > write_end_) { - LOG(DFATAL) << "bytes written = " << written - << " 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() + written, - write_end_ - written); - write_end_ -= written; - if (write_end_ > 0U) { - PostDoWrite(); - } -} - -// * -> STATE_CLOSED - -bool ChromeAsyncSocket::Close() { - DoClose(); - return true; -} - -// (not STATE_CLOSED) -> STATE_CLOSED - -void ChromeAsyncSocket::DoClose() { - weak_ptr_factory_.InvalidateWeakPtrs(); - if (transport_socket_.get()) { - transport_socket_->Disconnect(); - } - transport_socket_.reset(); - read_state_ = IDLE; - read_start_ = 0U; - read_end_ = 0U; - write_state_ = IDLE; - write_end_ = 0U; - 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_ = 0U; - read_end_ = 0U; - DCHECK_EQ(write_end_, 0U); - - // Clear out any posted DoRead() tasks. - weak_ptr_factory_.InvalidateWeakPtrs(); - - DCHECK(transport_socket_.get()); - scoped_ptr<net::ClientSocketHandle> socket_handle( - new net::ClientSocketHandle()); - socket_handle->set_socket(transport_socket_.release()); - transport_socket_.reset( - resolving_client_socket_factory_->CreateSSLClientSocket( - socket_handle.release(), net::HostPortPair(domain_name, 443))); - int status = transport_socket_->Connect( - base::Bind(&ChromeAsyncSocket::ProcessSSLConnectDone, - weak_ptr_factory_.GetWeakPtr())); - if (status != net::ERR_IO_PENDING) { - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - base::Bind(&ChromeAsyncSocket::ProcessSSLConnectDone, - weak_ptr_factory_.GetWeakPtr(), 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_, 0U); - DCHECK_EQ(read_end_, 0U); - DCHECK_EQ(write_state_, IDLE); - if (status != net::OK) { - DoNetErrorFromStatus(status); - DoClose(); - return; - } - state_ = STATE_TLS_OPEN; - PostDoRead(); - if (write_end_ > 0U) { - PostDoWrite(); - } - SignalSSLConnected(); -} - -} // namespace notifier diff --git a/jingle/notifier/base/chrome_async_socket.h b/jingle/notifier/base/chrome_async_socket.h deleted file mode 100644 index 8cf8e8d..0000000 --- a/jingle/notifier/base/chrome_async_socket.h +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2012 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 JINGLE_NOTIFIER_BASE_CHROME_ASYNC_SOCKET_H_ -#define JINGLE_NOTIFIER_BASE_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/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "net/base/completion_callback.h" -#include "net/base/net_errors.h" -#include "talk/xmpp/asyncsocket.h" - -namespace net { -class IOBufferWithSize; -class StreamSocket; -} // namespace net - -namespace notifier { - -class ResolvingClientSocketFactory; - -class ChromeAsyncSocket : public buzz::AsyncSocket { - public: - // Takes ownership of |resolving_client_socket_factory|. - ChromeAsyncSocket( - ResolvingClientSocketFactory* resolving_client_socket_factory, - size_t read_buf_size, - size_t write_buf_size); - - // 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() OVERRIDE; - - // 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() OVERRIDE; - - // GetError() (which is of type net::Error) != net::OK only when - // error() == ERROR_WINSOCK. - virtual int GetError() OVERRIDE; - - // Tries to connect to the given address. - // - // If state() is not STATE_CLOSED, sets error to ERROR_WRONGSTATE - // and returns false. - // - // If |address| has an empty hostname or a zero port, sets error to - // ERROR_DNS and returns false. (We don't use the IP address even - // if it's present, as DNS resolution is done by - // |resolving_client_socket_factory_|. But it's perfectly fine if - // the hostname is a stringified IP address.) - // - // 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) OVERRIDE; - - // 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) OVERRIDE; - - // 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) OVERRIDE; - - // If the socket is not already closed, closes the socket and raises - // SignalClosed. Always returns true. - virtual bool Close() OVERRIDE; - - // 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) OVERRIDE; - - // 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(); - - base::WeakPtrFactory<ChromeAsyncSocket> weak_ptr_factory_; - scoped_ptr<ResolvingClientSocketFactory> resolving_client_socket_factory_; - - // buzz::AsyncSocket state. - buzz::AsyncSocket::State state_; - buzz::AsyncSocket::Error error_; - net::Error net_error_; - - // NULL iff state() == STATE_CLOSED. - scoped_ptr<net::StreamSocket> 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 notifier - -#endif // JINGLE_NOTIFIER_BASE_CHROME_ASYNC_SOCKET_H_ diff --git a/jingle/notifier/base/chrome_async_socket_unittest.cc b/jingle/notifier/base/chrome_async_socket_unittest.cc deleted file mode 100644 index ce97531..0000000 --- a/jingle/notifier/base/chrome_async_socket_unittest.cc +++ /dev/null @@ -1,1079 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/chrome_async_socket.h" - -#include <deque> -#include <string> - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "jingle/notifier/base/resolving_client_socket_factory.h" -#include "net/base/address_list.h" -#include "net/base/mock_cert_verifier.h" -#include "net/base/net_errors.h" -#include "net/base/net_util.h" -#include "net/base/ssl_config_service.h" -#include "net/socket/socket_test_util.h" -#include "net/socket/ssl_client_socket.h" -#include "net/url_request/url_request_context_getter.h" -#include "talk/base/sigslot.h" -#include "talk/base/ipaddress.h" -#include "talk/base/socketaddress.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace notifier { - -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(net::SYNCHRONOUS, 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.mode, 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(net::SYNCHRONOUS, net::ERR_UNEXPECTED); - } - return net::MockWriteResult(mock_write.mode, 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 MockXmppClientSocketFactory : public ResolvingClientSocketFactory { - public: - MockXmppClientSocketFactory( - net::ClientSocketFactory* mock_client_socket_factory, - const net::AddressList& address_list) - : mock_client_socket_factory_(mock_client_socket_factory), - address_list_(address_list), - cert_verifier_(new net::MockCertVerifier) { - } - - // ResolvingClientSocketFactory implementation. - virtual net::StreamSocket* CreateTransportClientSocket( - const net::HostPortPair& host_and_port) { - return mock_client_socket_factory_->CreateTransportClientSocket( - address_list_, NULL, net::NetLog::Source()); - } - - virtual net::SSLClientSocket* CreateSSLClientSocket( - net::ClientSocketHandle* transport_socket, - const net::HostPortPair& host_and_port) { - net::SSLClientSocketContext context; - context.cert_verifier = cert_verifier_.get(); - return mock_client_socket_factory_->CreateSSLClientSocket( - transport_socket, host_and_port, ssl_config_, context); - } - - private: - scoped_ptr<net::ClientSocketFactory> mock_client_socket_factory_; - net::AddressList address_list_; - net::SSLConfig ssl_config_; - scoped_ptr<net::CertVerifier> cert_verifier_; -}; - -class ChromeAsyncSocketTest - : public testing::Test, - public sigslot::has_slots<> { - protected: - ChromeAsyncSocketTest() - : ssl_socket_data_provider_(net::ASYNC, net::OK), - addr_("localhost", 35) {} - - virtual ~ChromeAsyncSocketTest() {} - - virtual void SetUp() { - scoped_ptr<net::MockClientSocketFactory> mock_client_socket_factory( - new net::MockClientSocketFactory()); - mock_client_socket_factory->AddSocketDataProvider( - &async_socket_data_provider_); - mock_client_socket_factory->AddSSLSocketDataProvider( - &ssl_socket_data_provider_); - - // Fake DNS resolution for |addr_| and pass it to the factory. - net::IPAddressNumber resolved_addr; - EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &resolved_addr)); - const net::AddressList address_list = - net::AddressList::CreateFromIPAddress(resolved_addr, addr_.port()); - scoped_ptr<MockXmppClientSocketFactory> mock_xmpp_client_socket_factory( - new MockXmppClientSocketFactory( - mock_client_socket_factory.release(), - address_list)); - chrome_async_socket_.reset( - new ChromeAsyncSocket(mock_xmpp_client_socket_factory.release(), - 14, 20)), - - 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_.reset(); - } - - 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_.get())); - } - - 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(net::SYNCHRONOUS, 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 == 0U) { - break; - } - read.append(buf.get(), len_read); - } - return read; - } - - // ChromeAsyncSocket expects a message loop. - MessageLoop message_loop_; - - AsyncSocketDataProvider async_socket_data_provider_; - net::SSLSocketDataProvider ssl_socket_data_provider_; - - scoped_ptr<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, NoHostnameConnect) { - talk_base::IPAddress ip_address; - EXPECT_TRUE(talk_base::IPFromString("127.0.0.1", &ip_address)); - const talk_base::SocketAddress no_hostname_addr(ip_address, addr_.port()); - EXPECT_FALSE(chrome_async_socket_->Connect(no_hostname_addr)); - ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_DNS); - - EXPECT_TRUE(chrome_async_socket_->Close()); - ExpectClosed(); -} - -TEST_F(ChromeAsyncSocketTest, ZeroPortConnect) { - const talk_base::SocketAddress zero_port_addr(addr_.hostname(), 0); - EXPECT_FALSE(chrome_async_socket_->Connect(zero_port_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(net::ASYNC, 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(net::ASYNC, 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(net::ASYNC, 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 = 10000U; - EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); - EXPECT_EQ(0U, len_read); - - DoCloseOpenedNoError(); -} - -TEST_F(ChromeAsyncSocketTest, WrongRead) { - EXPECT_DEBUG_DEATH({ - async_socket_data_provider_.set_connect_data( - net::MockConnect(net::ASYNC, 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_CONNECTING, - ChromeAsyncSocket::ERROR_WRONGSTATE); - EXPECT_TRUE(chrome_async_socket_->Close()); - ExpectSignalSocketState( - SignalSocketState( - SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, - ChromeAsyncSocket::ERROR_WRONGSTATE, net::OK)); - }, "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(net::SYNCHRONOUS, 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(net::ASYNC, 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(net::SYNCHRONOUS, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::SYNCHRONOUS, - 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(net::ASYNC, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::ASYNC, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::ASYNC, 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(net::ASYNC, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::ASYNC, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::ASYNC, 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(net::ASYNC, 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 = 10000U; - EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); - EXPECT_EQ(0U, len_read); - - message_loop_.RunAllPending(); - ExpectSSLConnectSignal(); - ExpectSSLReadSignal(); - ExpectNoSignal(); - ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); - - len_read = 10000U; - 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(net::ASYNC, 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(net::ASYNC, 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(net::SYNCHRONOUS, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::SYNCHRONOUS, - 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(net::ASYNC, kWriteData, 3)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::ASYNC, kWriteData + 3, 5)); - async_socket_data_provider_.AddWrite( - net::MockWrite(net::ASYNC, 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 notifier diff --git a/jingle/notifier/base/fake_ssl_client_socket.cc b/jingle/notifier/base/fake_ssl_client_socket.cc deleted file mode 100644 index 3329e31..0000000 --- a/jingle/notifier/base/fake_ssl_client_socket.cc +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/fake_ssl_client_socket.h" - -#include <cstdlib> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" - -namespace notifier { - -namespace { - -// The constants below were taken from libjingle's socketadapters.cc. -// Basically, we do a "fake" SSL handshake to fool proxies into -// thinking this is a real SSL connection. - -// This is a SSL v2 CLIENT_HELLO message. -// TODO(juberti): Should this have a session id? The response doesn't have a -// certificate, so the hello should have a session id. -static const uint8 kSslClientHello[] = { - 0x80, 0x46, // msg len - 0x01, // CLIENT_HELLO - 0x03, 0x01, // SSL 3.1 - 0x00, 0x2d, // ciphersuite len - 0x00, 0x00, // session id len - 0x00, 0x10, // challenge len - 0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0, // ciphersuites - 0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80, // - 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a, // - 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, // - 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, // - 0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc, // challenge - 0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea // -}; - -// This is a TLSv1 SERVER_HELLO message. -static const uint8 kSslServerHello[] = { - 0x16, // handshake message - 0x03, 0x01, // SSL 3.1 - 0x00, 0x4a, // message len - 0x02, // SERVER_HELLO - 0x00, 0x00, 0x46, // handshake len - 0x03, 0x01, // SSL 3.1 - 0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0, // server random - 0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f, // - 0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1, // - 0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f, // - 0x20, // session id len - 0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f, // session id - 0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b, // - 0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38, // - 0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c, // - 0x00, 0x04, // RSA/RC4-128/MD5 - 0x00 // null compression -}; - -net::DrainableIOBuffer* NewDrainableIOBufferWithSize(int size) { - return new net::DrainableIOBuffer(new net::IOBuffer(size), size); -} - -} // namespace - -base::StringPiece FakeSSLClientSocket::GetSslClientHello() { - return base::StringPiece(reinterpret_cast<const char*>(kSslClientHello), - arraysize(kSslClientHello)); -} - -base::StringPiece FakeSSLClientSocket::GetSslServerHello() { - return base::StringPiece(reinterpret_cast<const char*>(kSslServerHello), - arraysize(kSslServerHello)); -} - -FakeSSLClientSocket::FakeSSLClientSocket( - net::StreamSocket* transport_socket) - : transport_socket_(transport_socket), - next_handshake_state_(STATE_NONE), - handshake_completed_(false), - write_buf_(NewDrainableIOBufferWithSize(arraysize(kSslClientHello))), - read_buf_(NewDrainableIOBufferWithSize(arraysize(kSslServerHello))) { - CHECK(transport_socket_.get()); - std::memcpy(write_buf_->data(), kSslClientHello, arraysize(kSslClientHello)); -} - -FakeSSLClientSocket::~FakeSSLClientSocket() {} - -int FakeSSLClientSocket::Read(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) { - DCHECK_EQ(next_handshake_state_, STATE_NONE); - DCHECK(handshake_completed_); - return transport_socket_->Read(buf, buf_len, callback); -} - -int FakeSSLClientSocket::Write(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) { - DCHECK_EQ(next_handshake_state_, STATE_NONE); - DCHECK(handshake_completed_); - return transport_socket_->Write(buf, buf_len, callback); -} - -bool FakeSSLClientSocket::SetReceiveBufferSize(int32 size) { - return transport_socket_->SetReceiveBufferSize(size); -} - -bool FakeSSLClientSocket::SetSendBufferSize(int32 size) { - return transport_socket_->SetSendBufferSize(size); -} - -int FakeSSLClientSocket::Connect(const net::CompletionCallback& callback) { - // We don't support synchronous operation, even if - // |transport_socket_| does. - DCHECK(!callback.is_null()); - DCHECK_EQ(next_handshake_state_, STATE_NONE); - DCHECK(!handshake_completed_); - DCHECK(user_connect_callback_.is_null()); - DCHECK_EQ(write_buf_->BytesConsumed(), 0); - DCHECK_EQ(read_buf_->BytesConsumed(), 0); - - next_handshake_state_ = STATE_CONNECT; - int status = DoHandshakeLoop(); - if (status == net::ERR_IO_PENDING) - user_connect_callback_ = callback; - - return status; -} - -int FakeSSLClientSocket::DoHandshakeLoop() { - DCHECK_NE(next_handshake_state_, STATE_NONE); - int status = net::OK; - do { - HandshakeState state = next_handshake_state_; - next_handshake_state_ = STATE_NONE; - switch (state) { - case STATE_CONNECT: - status = DoConnect(); - break; - case STATE_SEND_CLIENT_HELLO: - status = DoSendClientHello(); - break; - case STATE_VERIFY_SERVER_HELLO: - status = DoVerifyServerHello(); - break; - default: - status = net::ERR_UNEXPECTED; - LOG(DFATAL) << "unexpected state: " << state; - break; - } - } while ((status != net::ERR_IO_PENDING) && - (next_handshake_state_ != STATE_NONE)); - return status; -} - -void FakeSSLClientSocket::RunUserConnectCallback(int status) { - DCHECK_LE(status, net::OK); - next_handshake_state_ = STATE_NONE; - net::CompletionCallback user_connect_callback = user_connect_callback_; - user_connect_callback_.Reset(); - user_connect_callback.Run(status); -} - -void FakeSSLClientSocket::DoHandshakeLoopWithUserConnectCallback() { - int status = DoHandshakeLoop(); - if (status != net::ERR_IO_PENDING) { - RunUserConnectCallback(status); - } -} - -int FakeSSLClientSocket::DoConnect() { - int status = transport_socket_->Connect( - base::Bind(&FakeSSLClientSocket::OnConnectDone, base::Unretained(this))); - if (status != net::OK) { - return status; - } - ProcessConnectDone(); - return net::OK; -} - -void FakeSSLClientSocket::OnConnectDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK_LE(status, net::OK); - DCHECK(!user_connect_callback_.is_null()); - if (status != net::OK) { - RunUserConnectCallback(status); - return; - } - ProcessConnectDone(); - DoHandshakeLoopWithUserConnectCallback(); -} - -void FakeSSLClientSocket::ProcessConnectDone() { - DCHECK_EQ(write_buf_->BytesConsumed(), 0); - DCHECK_EQ(read_buf_->BytesConsumed(), 0); - next_handshake_state_ = STATE_SEND_CLIENT_HELLO; -} - -int FakeSSLClientSocket::DoSendClientHello() { - int status = transport_socket_->Write( - write_buf_, write_buf_->BytesRemaining(), - base::Bind(&FakeSSLClientSocket::OnSendClientHelloDone, - base::Unretained(this))); - if (status < net::OK) { - return status; - } - ProcessSendClientHelloDone(static_cast<size_t>(status)); - return net::OK; -} - -void FakeSSLClientSocket::OnSendClientHelloDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK(!user_connect_callback_.is_null()); - if (status < net::OK) { - RunUserConnectCallback(status); - return; - } - ProcessSendClientHelloDone(static_cast<size_t>(status)); - DoHandshakeLoopWithUserConnectCallback(); -} - -void FakeSSLClientSocket::ProcessSendClientHelloDone(size_t written) { - DCHECK_LE(written, static_cast<size_t>(write_buf_->BytesRemaining())); - DCHECK_EQ(read_buf_->BytesConsumed(), 0); - if (written < static_cast<size_t>(write_buf_->BytesRemaining())) { - next_handshake_state_ = STATE_SEND_CLIENT_HELLO; - write_buf_->DidConsume(written); - } else { - next_handshake_state_ = STATE_VERIFY_SERVER_HELLO; - } -} - -int FakeSSLClientSocket::DoVerifyServerHello() { - int status = transport_socket_->Read( - read_buf_, read_buf_->BytesRemaining(), - base::Bind(&FakeSSLClientSocket::OnVerifyServerHelloDone, - base::Unretained(this))); - if (status < net::OK) { - return status; - } - size_t read = static_cast<size_t>(status); - return ProcessVerifyServerHelloDone(read); -} - -void FakeSSLClientSocket::OnVerifyServerHelloDone(int status) { - DCHECK_NE(status, net::ERR_IO_PENDING); - DCHECK(!user_connect_callback_.is_null()); - if (status < net::OK) { - RunUserConnectCallback(status); - return; - } - size_t read = static_cast<size_t>(status); - status = ProcessVerifyServerHelloDone(read); - if (status < net::OK) { - RunUserConnectCallback(status); - return; - } - if (handshake_completed_) { - RunUserConnectCallback(net::OK); - } else { - DoHandshakeLoopWithUserConnectCallback(); - } -} - -net::Error FakeSSLClientSocket::ProcessVerifyServerHelloDone(size_t read) { - DCHECK_LE(read, static_cast<size_t>(read_buf_->BytesRemaining())); - if (read == 0U) { - return net::ERR_UNEXPECTED; - } - const uint8* expected_data_start = - &kSslServerHello[arraysize(kSslServerHello) - - read_buf_->BytesRemaining()]; - if (std::memcmp(expected_data_start, read_buf_->data(), read) != 0) { - return net::ERR_UNEXPECTED; - } - if (read < static_cast<size_t>(read_buf_->BytesRemaining())) { - next_handshake_state_ = STATE_VERIFY_SERVER_HELLO; - read_buf_->DidConsume(read); - } else { - next_handshake_state_ = STATE_NONE; - handshake_completed_ = true; - } - return net::OK; -} - -void FakeSSLClientSocket::Disconnect() { - transport_socket_->Disconnect(); - next_handshake_state_ = STATE_NONE; - handshake_completed_ = false; - user_connect_callback_.Reset(); - write_buf_->SetOffset(0); - read_buf_->SetOffset(0); -} - -bool FakeSSLClientSocket::IsConnected() const { - return handshake_completed_ && transport_socket_->IsConnected(); -} - -bool FakeSSLClientSocket::IsConnectedAndIdle() const { - return handshake_completed_ && transport_socket_->IsConnectedAndIdle(); -} - -int FakeSSLClientSocket::GetPeerAddress(net::IPEndPoint* address) const { - return transport_socket_->GetPeerAddress(address); -} - -int FakeSSLClientSocket::GetLocalAddress(net::IPEndPoint* address) const { - return transport_socket_->GetLocalAddress(address); -} - -const net::BoundNetLog& FakeSSLClientSocket::NetLog() const { - return transport_socket_->NetLog(); -} - -void FakeSSLClientSocket::SetSubresourceSpeculation() { - transport_socket_->SetSubresourceSpeculation(); -} - -void FakeSSLClientSocket::SetOmniboxSpeculation() { - transport_socket_->SetOmniboxSpeculation(); -} - -bool FakeSSLClientSocket::WasEverUsed() const { - return transport_socket_->WasEverUsed(); -} - -bool FakeSSLClientSocket::UsingTCPFastOpen() const { - return transport_socket_->UsingTCPFastOpen(); -} - -int64 FakeSSLClientSocket::NumBytesRead() const { - return transport_socket_->NumBytesRead(); -} - -base::TimeDelta FakeSSLClientSocket::GetConnectTimeMicros() const { - return transport_socket_->GetConnectTimeMicros(); -} - -bool FakeSSLClientSocket::WasNpnNegotiated() const { - return transport_socket_->WasNpnNegotiated(); -} - -net::NextProto FakeSSLClientSocket::GetNegotiatedProtocol() const { - return transport_socket_->GetNegotiatedProtocol(); -} - -bool FakeSSLClientSocket::GetSSLInfo(net::SSLInfo* ssl_info) { - return transport_socket_->GetSSLInfo(ssl_info); -} - -} // namespace notifier diff --git a/jingle/notifier/base/fake_ssl_client_socket.h b/jingle/notifier/base/fake_ssl_client_socket.h deleted file mode 100644 index b9df8a6..0000000 --- a/jingle/notifier/base/fake_ssl_client_socket.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2012 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. -// -// This StreamSocket implementation is to be used with servers that -// accept connections on port 443 but don't really use SSL. For -// example, the Google Talk servers do this to bypass proxies. (The -// connection is upgraded to TLS as part of the XMPP negotiation, so -// security is preserved.) A "fake" SSL handshake is done immediately -// after connection to fool proxies into thinking that this is a real -// SSL connection. -// -// NOTE: This StreamSocket implementation does *not* do a real SSL -// handshake nor does it do any encryption! - -#ifndef JINGLE_NOTIFIER_BASE_FAKE_SSL_CLIENT_SOCKET_H_ -#define JINGLE_NOTIFIER_BASE_FAKE_SSL_CLIENT_SOCKET_H_ - -#include <cstddef> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/string_piece.h" -#include "net/base/completion_callback.h" -#include "net/base/net_errors.h" -#include "net/socket/stream_socket.h" - -namespace net { -class DrainableIOBuffer; -class SSLInfo; -} // namespace net - -namespace notifier { - -class FakeSSLClientSocket : public net::StreamSocket { - public: - // Takes ownership of |transport_socket|. - explicit FakeSSLClientSocket(net::StreamSocket* transport_socket); - - virtual ~FakeSSLClientSocket(); - - // Exposed for testing. - static base::StringPiece GetSslClientHello(); - static base::StringPiece GetSslServerHello(); - - // net::StreamSocket implementation. - virtual int Read(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) OVERRIDE; - virtual int Write(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) OVERRIDE; - virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; - virtual bool SetSendBufferSize(int32 size) OVERRIDE; - virtual int Connect(const net::CompletionCallback& callback) OVERRIDE; - virtual void Disconnect() OVERRIDE; - virtual bool IsConnected() const OVERRIDE; - virtual bool IsConnectedAndIdle() const OVERRIDE; - virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE; - virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE; - virtual const net::BoundNetLog& NetLog() const OVERRIDE; - virtual void SetSubresourceSpeculation() OVERRIDE; - virtual void SetOmniboxSpeculation() OVERRIDE; - virtual bool WasEverUsed() const OVERRIDE; - virtual bool UsingTCPFastOpen() const OVERRIDE; - virtual int64 NumBytesRead() const OVERRIDE; - virtual base::TimeDelta GetConnectTimeMicros() const OVERRIDE; - virtual bool WasNpnNegotiated() const OVERRIDE; - virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE; - virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE; - - private: - enum HandshakeState { - STATE_NONE, - STATE_CONNECT, - STATE_SEND_CLIENT_HELLO, - STATE_VERIFY_SERVER_HELLO, - }; - - int DoHandshakeLoop(); - void RunUserConnectCallback(int status); - void DoHandshakeLoopWithUserConnectCallback(); - - int DoConnect(); - void OnConnectDone(int status); - void ProcessConnectDone(); - - int DoSendClientHello(); - void OnSendClientHelloDone(int status); - void ProcessSendClientHelloDone(size_t written); - - int DoVerifyServerHello(); - void OnVerifyServerHelloDone(int status); - net::Error ProcessVerifyServerHelloDone(size_t read); - - scoped_ptr<net::StreamSocket> transport_socket_; - - // During the handshake process, holds a value from HandshakeState. - // STATE_NONE otherwise. - HandshakeState next_handshake_state_; - - // True iff we're connected and we've finished the handshake. - bool handshake_completed_; - - // The callback passed to Connect(). - net::CompletionCallback user_connect_callback_; - - scoped_refptr<net::DrainableIOBuffer> write_buf_; - scoped_refptr<net::DrainableIOBuffer> read_buf_; -}; - -} // namespace notifier - -#endif // JINGLE_NOTIFIER_BASE_FAKE_SSL_CLIENT_SOCKET_H_ diff --git a/jingle/notifier/base/fake_ssl_client_socket_unittest.cc b/jingle/notifier/base/fake_ssl_client_socket_unittest.cc deleted file mode 100644 index 617e4d1..0000000 --- a/jingle/notifier/base/fake_ssl_client_socket_unittest.cc +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/fake_ssl_client_socket.h" - -#include <algorithm> -#include <vector> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "net/base/io_buffer.h" -#include "net/base/net_log.h" -#include "net/base/test_completion_callback.h" -#include "net/socket/socket_test_util.h" -#include "net/socket/stream_socket.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace notifier { - -namespace { - -using ::testing::Return; -using ::testing::ReturnRef; - -// Used by RunUnsuccessfulHandshakeTestHelper. Represents where in -// the handshake step an error should be inserted. -enum HandshakeErrorLocation { - CONNECT_ERROR, - SEND_CLIENT_HELLO_ERROR, - VERIFY_SERVER_HELLO_ERROR, -}; - -// Private error codes appended to the net::Error set. -enum { - // An error representing a server hello that has been corrupted in - // transit. - ERR_MALFORMED_SERVER_HELLO = -15000, -}; - -// Used by PassThroughMethods test. -class MockClientSocket : public net::StreamSocket { - public: - virtual ~MockClientSocket() {} - - MOCK_METHOD3(Read, int(net::IOBuffer*, int, - const net::CompletionCallback&)); - MOCK_METHOD3(Write, int(net::IOBuffer*, int, - const net::CompletionCallback&)); - MOCK_METHOD1(SetReceiveBufferSize, bool(int32)); - MOCK_METHOD1(SetSendBufferSize, bool(int32)); - MOCK_METHOD1(Connect, int(const net::CompletionCallback&)); - MOCK_METHOD0(Disconnect, void()); - MOCK_CONST_METHOD0(IsConnected, bool()); - MOCK_CONST_METHOD0(IsConnectedAndIdle, bool()); - MOCK_CONST_METHOD1(GetPeerAddress, int(net::IPEndPoint*)); - MOCK_CONST_METHOD1(GetLocalAddress, int(net::IPEndPoint*)); - MOCK_CONST_METHOD0(NetLog, const net::BoundNetLog&()); - MOCK_METHOD0(SetSubresourceSpeculation, void()); - MOCK_METHOD0(SetOmniboxSpeculation, void()); - MOCK_CONST_METHOD0(WasEverUsed, bool()); - MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); - MOCK_CONST_METHOD0(NumBytesRead, int64()); - MOCK_CONST_METHOD0(GetConnectTimeMicros, base::TimeDelta()); - MOCK_CONST_METHOD0(WasNpnNegotiated, bool()); - MOCK_CONST_METHOD0(GetNegotiatedProtocol, net::NextProto()); - MOCK_METHOD1(GetSSLInfo, bool(net::SSLInfo*)); -}; - -// Break up |data| into a bunch of chunked MockReads/Writes and push -// them onto |ops|. -void AddChunkedOps(base::StringPiece data, size_t chunk_size, net::IoMode mode, - std::vector<net::MockRead>* ops) { - DCHECK_GT(chunk_size, 0U); - size_t offset = 0; - while (offset < data.size()) { - size_t bounded_chunk_size = std::min(data.size() - offset, chunk_size); - // We take advantage of the fact that MockWrite is typedefed to - // MockRead. - ops->push_back(net::MockRead(mode, data.data() + offset, - bounded_chunk_size)); - offset += bounded_chunk_size; - } -} - -class FakeSSLClientSocketTest : public testing::Test { - protected: - FakeSSLClientSocketTest() {} - - virtual ~FakeSSLClientSocketTest() {} - - net::StreamSocket* MakeClientSocket() { - return mock_client_socket_factory_.CreateTransportClientSocket( - net::AddressList(), NULL, net::NetLog::Source()); - } - - void SetData(const net::MockConnect& mock_connect, - std::vector<net::MockRead>* reads, - std::vector<net::MockWrite>* writes) { - static_socket_data_provider_.reset( - new net::StaticSocketDataProvider( - reads->empty() ? NULL : &*reads->begin(), reads->size(), - writes->empty() ? NULL : &*writes->begin(), writes->size())); - static_socket_data_provider_->set_connect_data(mock_connect); - mock_client_socket_factory_.AddSocketDataProvider( - static_socket_data_provider_.get()); - } - - void ExpectStatus( - net::IoMode mode, int expected_status, int immediate_status, - net::TestCompletionCallback* test_completion_callback) { - if (mode == net::ASYNC) { - EXPECT_EQ(net::ERR_IO_PENDING, immediate_status); - int status = test_completion_callback->WaitForResult(); - EXPECT_EQ(expected_status, status); - } else { - EXPECT_EQ(expected_status, immediate_status); - } - } - - // Sets up the mock socket to generate a successful handshake - // (sliced up according to the parameters) and makes sure the - // FakeSSLClientSocket behaves as expected. - void RunSuccessfulHandshakeTest( - net::IoMode mode, size_t read_chunk_size, size_t write_chunk_size, - int num_resets) { - base::StringPiece ssl_client_hello = - FakeSSLClientSocket::GetSslClientHello(); - base::StringPiece ssl_server_hello = - FakeSSLClientSocket::GetSslServerHello(); - - net::MockConnect mock_connect(mode, net::OK); - std::vector<net::MockRead> reads; - std::vector<net::MockWrite> writes; - static const char kReadTestData[] = "read test data"; - static const char kWriteTestData[] = "write test data"; - for (int i = 0; i < num_resets + 1; ++i) { - SCOPED_TRACE(i); - AddChunkedOps(ssl_server_hello, read_chunk_size, mode, &reads); - AddChunkedOps(ssl_client_hello, write_chunk_size, mode, &writes); - reads.push_back( - net::MockRead(mode, kReadTestData, arraysize(kReadTestData))); - writes.push_back( - net::MockWrite(mode, kWriteTestData, arraysize(kWriteTestData))); - } - SetData(mock_connect, &reads, &writes); - - FakeSSLClientSocket fake_ssl_client_socket(MakeClientSocket()); - - for (int i = 0; i < num_resets + 1; ++i) { - SCOPED_TRACE(i); - net::TestCompletionCallback test_completion_callback; - int status = fake_ssl_client_socket.Connect( - test_completion_callback.callback()); - if (mode == net::ASYNC) { - EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); - } - ExpectStatus(mode, net::OK, status, &test_completion_callback); - if (fake_ssl_client_socket.IsConnected()) { - int read_len = arraysize(kReadTestData); - int read_buf_len = 2 * read_len; - scoped_refptr<net::IOBuffer> read_buf( - new net::IOBuffer(read_buf_len)); - int read_status = fake_ssl_client_socket.Read( - read_buf, read_buf_len, test_completion_callback.callback()); - ExpectStatus(mode, read_len, read_status, &test_completion_callback); - - scoped_refptr<net::IOBuffer> write_buf( - new net::StringIOBuffer(kWriteTestData)); - int write_status = fake_ssl_client_socket.Write( - write_buf, arraysize(kWriteTestData), - test_completion_callback.callback()); - ExpectStatus(mode, arraysize(kWriteTestData), write_status, - &test_completion_callback); - } else { - ADD_FAILURE(); - } - fake_ssl_client_socket.Disconnect(); - EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); - } - } - - // Sets up the mock socket to generate an unsuccessful handshake - // FakeSSLClientSocket fails as expected. - void RunUnsuccessfulHandshakeTestHelper( - net::IoMode mode, int error, HandshakeErrorLocation location) { - DCHECK_NE(error, net::OK); - base::StringPiece ssl_client_hello = - FakeSSLClientSocket::GetSslClientHello(); - base::StringPiece ssl_server_hello = - FakeSSLClientSocket::GetSslServerHello(); - - net::MockConnect mock_connect(mode, net::OK); - std::vector<net::MockRead> reads; - std::vector<net::MockWrite> writes; - const size_t kChunkSize = 1; - AddChunkedOps(ssl_server_hello, kChunkSize, mode, &reads); - AddChunkedOps(ssl_client_hello, kChunkSize, mode, &writes); - switch (location) { - case CONNECT_ERROR: - mock_connect.result = error; - writes.clear(); - reads.clear(); - break; - case SEND_CLIENT_HELLO_ERROR: { - // Use a fixed index for repeatability. - size_t index = 100 % writes.size(); - writes[index].result = error; - writes[index].data = NULL; - writes[index].data_len = 0; - writes.resize(index + 1); - reads.clear(); - break; - } - case VERIFY_SERVER_HELLO_ERROR: { - // Use a fixed index for repeatability. - size_t index = 50 % reads.size(); - if (error == ERR_MALFORMED_SERVER_HELLO) { - static const char kBadData[] = "BAD_DATA"; - reads[index].data = kBadData; - reads[index].data_len = arraysize(kBadData); - } else { - reads[index].result = error; - reads[index].data = NULL; - reads[index].data_len = 0; - } - reads.resize(index + 1); - if (error == - net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { - static const char kDummyData[] = "DUMMY"; - reads.push_back(net::MockRead(mode, kDummyData)); - } - break; - } - } - SetData(mock_connect, &reads, &writes); - - FakeSSLClientSocket fake_ssl_client_socket(MakeClientSocket()); - - // The two errors below are interpreted by FakeSSLClientSocket as - // an unexpected event. - int expected_status = - ((error == net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) || - (error == ERR_MALFORMED_SERVER_HELLO)) ? - net::ERR_UNEXPECTED : error; - - net::TestCompletionCallback test_completion_callback; - int status = fake_ssl_client_socket.Connect( - test_completion_callback.callback()); - EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); - ExpectStatus(mode, expected_status, status, &test_completion_callback); - EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); - } - - void RunUnsuccessfulHandshakeTest( - int error, HandshakeErrorLocation location) { - RunUnsuccessfulHandshakeTestHelper(net::SYNCHRONOUS, error, location); - RunUnsuccessfulHandshakeTestHelper(net::ASYNC, error, location); - } - - // MockTCPClientSocket needs a message loop. - MessageLoop message_loop_; - - net::MockClientSocketFactory mock_client_socket_factory_; - scoped_ptr<net::StaticSocketDataProvider> static_socket_data_provider_; -}; - -TEST_F(FakeSSLClientSocketTest, PassThroughMethods) { - MockClientSocket* mock_client_socket = new MockClientSocket(); - const int kReceiveBufferSize = 10; - const int kSendBufferSize = 20; - net::IPEndPoint ip_endpoint(net::IPAddressNumber(net::kIPv4AddressSize), 80); - const int kPeerAddress = 30; - net::BoundNetLog net_log; - EXPECT_CALL(*mock_client_socket, SetReceiveBufferSize(kReceiveBufferSize)); - EXPECT_CALL(*mock_client_socket, SetSendBufferSize(kSendBufferSize)); - EXPECT_CALL(*mock_client_socket, GetPeerAddress(&ip_endpoint)). - WillOnce(Return(kPeerAddress)); - EXPECT_CALL(*mock_client_socket, NetLog()).WillOnce(ReturnRef(net_log)); - EXPECT_CALL(*mock_client_socket, SetSubresourceSpeculation()); - EXPECT_CALL(*mock_client_socket, SetOmniboxSpeculation()); - - // Takes ownership of |mock_client_socket|. - FakeSSLClientSocket fake_ssl_client_socket(mock_client_socket); - fake_ssl_client_socket.SetReceiveBufferSize(kReceiveBufferSize); - fake_ssl_client_socket.SetSendBufferSize(kSendBufferSize); - EXPECT_EQ(kPeerAddress, - fake_ssl_client_socket.GetPeerAddress(&ip_endpoint)); - EXPECT_EQ(&net_log, &fake_ssl_client_socket.NetLog()); - fake_ssl_client_socket.SetSubresourceSpeculation(); - fake_ssl_client_socket.SetOmniboxSpeculation(); -} - -TEST_F(FakeSSLClientSocketTest, SuccessfulHandshakeSync) { - for (size_t i = 1; i < 100; i += 3) { - SCOPED_TRACE(i); - for (size_t j = 1; j < 100; j += 5) { - SCOPED_TRACE(j); - RunSuccessfulHandshakeTest(net::SYNCHRONOUS, i, j, 0); - } - } -} - -TEST_F(FakeSSLClientSocketTest, SuccessfulHandshakeAsync) { - for (size_t i = 1; i < 100; i += 7) { - SCOPED_TRACE(i); - for (size_t j = 1; j < 100; j += 9) { - SCOPED_TRACE(j); - RunSuccessfulHandshakeTest(net::ASYNC, i, j, 0); - } - } -} - -TEST_F(FakeSSLClientSocketTest, ResetSocket) { - RunSuccessfulHandshakeTest(net::ASYNC, 1, 2, 3); -} - -TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeConnectError) { - RunUnsuccessfulHandshakeTest(net::ERR_ACCESS_DENIED, CONNECT_ERROR); -} - -TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeWriteError) { - RunUnsuccessfulHandshakeTest(net::ERR_OUT_OF_MEMORY, - SEND_CLIENT_HELLO_ERROR); -} - -TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeReadError) { - RunUnsuccessfulHandshakeTest(net::ERR_CONNECTION_CLOSED, - VERIFY_SERVER_HELLO_ERROR); -} - -TEST_F(FakeSSLClientSocketTest, PeerClosedDuringHandshake) { - RunUnsuccessfulHandshakeTest( - net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, - VERIFY_SERVER_HELLO_ERROR); -} - -TEST_F(FakeSSLClientSocketTest, MalformedServerHello) { - RunUnsuccessfulHandshakeTest(ERR_MALFORMED_SERVER_HELLO, - VERIFY_SERVER_HELLO_ERROR); -} - -} // namespace - -} // namespace notifier diff --git a/jingle/notifier/base/proxy_resolving_client_socket.cc b/jingle/notifier/base/proxy_resolving_client_socket.cc deleted file mode 100644 index eb14d56..0000000 --- a/jingle/notifier/base/proxy_resolving_client_socket.cc +++ /dev/null @@ -1,392 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/proxy_resolving_client_socket.h" - -#include "base/basictypes.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "googleurl/src/gurl.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/http/http_network_session.h" -#include "net/socket/client_socket_handle.h" -#include "net/socket/client_socket_pool_manager.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" - -namespace notifier { - -ProxyResolvingClientSocket::ProxyResolvingClientSocket( - net::ClientSocketFactory* socket_factory, - const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, - const net::SSLConfig& ssl_config, - const net::HostPortPair& dest_host_port_pair) - : ALLOW_THIS_IN_INITIALIZER_LIST(proxy_resolve_callback_( - base::Bind(&ProxyResolvingClientSocket::ProcessProxyResolveDone, - base::Unretained(this)))), - ALLOW_THIS_IN_INITIALIZER_LIST(connect_callback_( - base::Bind(&ProxyResolvingClientSocket::ProcessConnectDone, - base::Unretained(this)))), - ssl_config_(ssl_config), - pac_request_(NULL), - dest_host_port_pair_(dest_host_port_pair), - tried_direct_connect_fallback_(false), - bound_net_log_( - net::BoundNetLog::Make( - request_context_getter->GetURLRequestContext()->net_log(), - net::NetLog::SOURCE_SOCKET)), - ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { - DCHECK(request_context_getter); - net::URLRequestContext* request_context = - request_context_getter->GetURLRequestContext(); - DCHECK(request_context); - DCHECK(!dest_host_port_pair_.host().empty()); - DCHECK_GT(dest_host_port_pair_.port(), 0); - net::HttpNetworkSession::Params session_params; - session_params.client_socket_factory = socket_factory; - session_params.host_resolver = request_context->host_resolver(); - session_params.cert_verifier = request_context->cert_verifier(); - // TODO(rkn): This is NULL because ServerBoundCertService is not thread safe. - session_params.server_bound_cert_service = NULL; - // transport_security_state is NULL because it's not thread safe. - session_params.transport_security_state = NULL; - session_params.proxy_service = request_context->proxy_service(); - session_params.ssl_config_service = request_context->ssl_config_service(); - session_params.http_auth_handler_factory = - request_context->http_auth_handler_factory(); - session_params.network_delegate = request_context->network_delegate(); - session_params.http_server_properties = - request_context->http_server_properties(); - session_params.net_log = request_context->net_log(); - network_session_ = new net::HttpNetworkSession(session_params); -} - -ProxyResolvingClientSocket::~ProxyResolvingClientSocket() { - Disconnect(); -} - -int ProxyResolvingClientSocket::Read(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) { - if (transport_.get() && transport_->socket()) - return transport_->socket()->Read(buf, buf_len, callback); - NOTREACHED(); - return net::ERR_SOCKET_NOT_CONNECTED; -} - -int ProxyResolvingClientSocket::Write( - net::IOBuffer* buf, - int buf_len, - const net::CompletionCallback& callback) { - if (transport_.get() && transport_->socket()) - return transport_->socket()->Write(buf, buf_len, callback); - NOTREACHED(); - return net::ERR_SOCKET_NOT_CONNECTED; -} - -bool ProxyResolvingClientSocket::SetReceiveBufferSize(int32 size) { - if (transport_.get() && transport_->socket()) - return transport_->socket()->SetReceiveBufferSize(size); - NOTREACHED(); - return false; -} - -bool ProxyResolvingClientSocket::SetSendBufferSize(int32 size) { - if (transport_.get() && transport_->socket()) - return transport_->socket()->SetSendBufferSize(size); - NOTREACHED(); - return false; -} - -int ProxyResolvingClientSocket::Connect( - const net::CompletionCallback& callback) { - DCHECK(user_connect_callback_.is_null()); - - tried_direct_connect_fallback_ = false; - - // First we try and resolve the proxy. - GURL url("http://" + dest_host_port_pair_.ToString()); - DCHECK(url.is_valid()); - int status = network_session_->proxy_service()->ResolveProxy( - url, - &proxy_info_, - proxy_resolve_callback_, - &pac_request_, - bound_net_log_); - if (status != net::ERR_IO_PENDING) { - // We defer execution of ProcessProxyResolveDone instead of calling it - // directly here for simplicity. 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, - base::Bind(&ProxyResolvingClientSocket::ProcessProxyResolveDone, - weak_factory_.GetWeakPtr(), status)); - } - user_connect_callback_ = callback; - return net::ERR_IO_PENDING; -} - -void ProxyResolvingClientSocket::RunUserConnectCallback(int status) { - DCHECK_LE(status, net::OK); - net::CompletionCallback user_connect_callback = user_connect_callback_; - user_connect_callback_.Reset(); - user_connect_callback.Run(status); -} - -// Always runs asynchronously. -void ProxyResolvingClientSocket::ProcessProxyResolveDone(int status) { - pac_request_ = NULL; - - DCHECK_NE(status, net::ERR_IO_PENDING); - if (status == net::OK) { - // Remove unsupported proxies from the list. - proxy_info_.RemoveProxiesWithoutScheme( - net::ProxyServer::SCHEME_DIRECT | - net::ProxyServer::SCHEME_HTTP | net::ProxyServer::SCHEME_HTTPS | - net::ProxyServer::SCHEME_SOCKS4 | net::ProxyServer::SCHEME_SOCKS5); - - if (proxy_info_.is_empty()) { - // No proxies/direct to choose from. This happens when we don't support - // any of the proxies in the returned list. - status = net::ERR_NO_SUPPORTED_PROXIES; - } - } - - // Since we are faking the URL, it is possible that no proxies match our URL. - // Try falling back to a direct connection if we have not tried that before. - if (status != net::OK) { - if (!tried_direct_connect_fallback_) { - tried_direct_connect_fallback_ = true; - proxy_info_.UseDirect(); - } else { - CloseTransportSocket(); - RunUserConnectCallback(status); - return; - } - } - - transport_.reset(new net::ClientSocketHandle); - // Now that we have resolved the proxy, we need to connect. - status = net::InitSocketHandleForRawConnect( - dest_host_port_pair_, network_session_.get(), proxy_info_, ssl_config_, - ssl_config_, bound_net_log_, transport_.get(), connect_callback_); - if (status != net::ERR_IO_PENDING) { - // Since this method is always called asynchronously. it is OK to call - // ProcessConnectDone synchronously. - ProcessConnectDone(status); - } -} - -void ProxyResolvingClientSocket::ProcessConnectDone(int status) { - if (status != net::OK) { - // If the connection fails, try another proxy. - status = ReconsiderProxyAfterError(status); - // ReconsiderProxyAfterError either returns an error (in which case it is - // not reconsidering a proxy) or returns ERR_IO_PENDING if it is considering - // another proxy. - DCHECK_NE(status, net::OK); - if (status == net::ERR_IO_PENDING) - // Proxy reconsideration pending. Return. - return; - CloseTransportSocket(); - } else { - ReportSuccessfulProxyConnection(); - } - RunUserConnectCallback(status); -} - -// TODO(sanjeevr): This has largely been copied from -// HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError. This should be -// refactored into some common place. -// This method reconsiders the proxy on certain errors. If it does reconsider -// a proxy it always returns ERR_IO_PENDING and posts a call to -// ProcessProxyResolveDone with the result of the reconsideration. -int ProxyResolvingClientSocket::ReconsiderProxyAfterError(int error) { - DCHECK(!pac_request_); - DCHECK_NE(error, net::OK); - DCHECK_NE(error, net::ERR_IO_PENDING); - // A failure to resolve the hostname or any error related to establishing a - // TCP connection could be grounds for trying a new proxy configuration. - // - // Why do this when a hostname cannot be resolved? Some URLs only make sense - // to proxy servers. The hostname in those URLs might fail to resolve if we - // are still using a non-proxy config. We need to check if a proxy config - // now exists that corresponds to a proxy server that could load the URL. - // - switch (error) { - case net::ERR_PROXY_CONNECTION_FAILED: - case net::ERR_NAME_NOT_RESOLVED: - case net::ERR_INTERNET_DISCONNECTED: - case net::ERR_ADDRESS_UNREACHABLE: - case net::ERR_CONNECTION_CLOSED: - case net::ERR_CONNECTION_RESET: - case net::ERR_CONNECTION_REFUSED: - case net::ERR_CONNECTION_ABORTED: - case net::ERR_TIMED_OUT: - case net::ERR_TUNNEL_CONNECTION_FAILED: - case net::ERR_SOCKS_CONNECTION_FAILED: - break; - case net::ERR_SOCKS_CONNECTION_HOST_UNREACHABLE: - // Remap the SOCKS-specific "host unreachable" error to a more - // generic error code (this way consumers like the link doctor - // know to substitute their error page). - // - // Note that if the host resolving was done by the SOCSK5 proxy, we can't - // differentiate between a proxy-side "host not found" versus a proxy-side - // "address unreachable" error, and will report both of these failures as - // ERR_ADDRESS_UNREACHABLE. - return net::ERR_ADDRESS_UNREACHABLE; - default: - return error; - } - - if (proxy_info_.is_https() && ssl_config_.send_client_cert) { - network_session_->ssl_client_auth_cache()->Remove( - proxy_info_.proxy_server().host_port_pair().ToString()); - } - - GURL url("http://" + dest_host_port_pair_.ToString()); - int rv = network_session_->proxy_service()->ReconsiderProxyAfterError( - url, &proxy_info_, proxy_resolve_callback_, &pac_request_, - bound_net_log_); - if (rv == net::OK || rv == net::ERR_IO_PENDING) { - CloseTransportSocket(); - } else { - // If ReconsiderProxyAfterError() failed synchronously, it means - // there was nothing left to fall-back to, so fail the transaction - // with the last connection error we got. - rv = error; - } - - // We either have new proxy info or there was an error in falling back. - // In both cases we want to post ProcessProxyResolveDone (in the error case - // we might still want to fall back a direct connection). - if (rv != net::ERR_IO_PENDING) { - MessageLoop* message_loop = MessageLoop::current(); - CHECK(message_loop); - message_loop->PostTask( - FROM_HERE, - base::Bind(&ProxyResolvingClientSocket::ProcessProxyResolveDone, - weak_factory_.GetWeakPtr(), rv)); - // Since we potentially have another try to go (trying the direct connect) - // set the return code code to ERR_IO_PENDING. - rv = net::ERR_IO_PENDING; - } - return rv; -} - -void ProxyResolvingClientSocket::ReportSuccessfulProxyConnection() { - network_session_->proxy_service()->ReportSuccess(proxy_info_); -} - -void ProxyResolvingClientSocket::Disconnect() { - CloseTransportSocket(); - if (pac_request_) - network_session_->proxy_service()->CancelPacRequest(pac_request_); - user_connect_callback_.Reset(); -} - -bool ProxyResolvingClientSocket::IsConnected() const { - if (!transport_.get() || !transport_->socket()) - return false; - return transport_->socket()->IsConnected(); -} - -bool ProxyResolvingClientSocket::IsConnectedAndIdle() const { - if (!transport_.get() || !transport_->socket()) - return false; - return transport_->socket()->IsConnectedAndIdle(); -} - -int ProxyResolvingClientSocket::GetPeerAddress( - net::IPEndPoint* address) const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->GetPeerAddress(address); - NOTREACHED(); - return net::ERR_SOCKET_NOT_CONNECTED; -} - -int ProxyResolvingClientSocket::GetLocalAddress( - net::IPEndPoint* address) const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->GetLocalAddress(address); - NOTREACHED(); - return net::ERR_SOCKET_NOT_CONNECTED; -} - -const net::BoundNetLog& ProxyResolvingClientSocket::NetLog() const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->NetLog(); - NOTREACHED(); - return bound_net_log_; -} - -void ProxyResolvingClientSocket::SetSubresourceSpeculation() { - if (transport_.get() && transport_->socket()) - transport_->socket()->SetSubresourceSpeculation(); - else - NOTREACHED(); -} - -void ProxyResolvingClientSocket::SetOmniboxSpeculation() { - if (transport_.get() && transport_->socket()) - transport_->socket()->SetOmniboxSpeculation(); - else - NOTREACHED(); -} - -bool ProxyResolvingClientSocket::WasEverUsed() const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->WasEverUsed(); - NOTREACHED(); - return false; -} - -bool ProxyResolvingClientSocket::UsingTCPFastOpen() const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->UsingTCPFastOpen(); - NOTREACHED(); - return false; -} - -int64 ProxyResolvingClientSocket::NumBytesRead() const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->NumBytesRead(); - NOTREACHED(); - return -1; -} - -base::TimeDelta ProxyResolvingClientSocket::GetConnectTimeMicros() const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->GetConnectTimeMicros(); - NOTREACHED(); - return base::TimeDelta::FromMicroseconds(-1); -} - -bool ProxyResolvingClientSocket::WasNpnNegotiated() const { - return false; -} - -net::NextProto ProxyResolvingClientSocket::GetNegotiatedProtocol() const { - if (transport_.get() && transport_->socket()) - return transport_->socket()->GetNegotiatedProtocol(); - NOTREACHED(); - return net::kProtoUnknown; -} - -bool ProxyResolvingClientSocket::GetSSLInfo(net::SSLInfo* ssl_info) { - return false; -} - -void ProxyResolvingClientSocket::CloseTransportSocket() { - if (transport_.get() && transport_->socket()) - transport_->socket()->Disconnect(); - transport_.reset(); -} - -} // namespace notifier diff --git a/jingle/notifier/base/proxy_resolving_client_socket.h b/jingle/notifier/base/proxy_resolving_client_socket.h deleted file mode 100644 index e2426ec..0000000 --- a/jingle/notifier/base/proxy_resolving_client_socket.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2012 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. -// -// This StreamSocket implementation wraps a ClientSocketHandle that is created -// from the client socket pool after resolving proxies. - -#ifndef JINGLE_NOTIFIER_BASE_PROXY_RESOLVING_CLIENT_SOCKET_H_ -#define JINGLE_NOTIFIER_BASE_PROXY_RESOLVING_CLIENT_SOCKET_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "net/base/completion_callback.h" -#include "net/base/host_port_pair.h" -#include "net/base/net_errors.h" -#include "net/base/net_log.h" -#include "net/base/ssl_config_service.h" -#include "net/proxy/proxy_info.h" -#include "net/proxy/proxy_service.h" -#include "net/socket/stream_socket.h" - -namespace net { -class ClientSocketFactory; -class ClientSocketHandle; -class HttpNetworkSession; -class URLRequestContextGetter; -} // namespace net - -// TODO(sanjeevr): Move this to net/ -namespace notifier { - -class ProxyResolvingClientSocket : public net::StreamSocket { - public: - // Constructs a new ProxyResolvingClientSocket. |socket_factory| is - // the ClientSocketFactory that will be used by the underlying - // HttpNetworkSession. If |socket_factory| is NULL, the default - // socket factory (net::ClientSocketFactory::GetDefaultFactory()) - // will be used. |dest_host_port_pair| is the destination for this - // socket. The hostname must be non-empty and the port must be > 0. - ProxyResolvingClientSocket( - net::ClientSocketFactory* socket_factory, - const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, - const net::SSLConfig& ssl_config, - const net::HostPortPair& dest_host_port_pair); - virtual ~ProxyResolvingClientSocket(); - - // net::StreamSocket implementation. - virtual int Read(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) OVERRIDE; - virtual int Write(net::IOBuffer* buf, int buf_len, - const net::CompletionCallback& callback) OVERRIDE; - virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; - virtual bool SetSendBufferSize(int32 size) OVERRIDE; - virtual int Connect(const net::CompletionCallback& callback) OVERRIDE; - virtual void Disconnect() OVERRIDE; - virtual bool IsConnected() const OVERRIDE; - virtual bool IsConnectedAndIdle() const OVERRIDE; - virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE; - virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE; - virtual const net::BoundNetLog& NetLog() const OVERRIDE; - virtual void SetSubresourceSpeculation() OVERRIDE; - virtual void SetOmniboxSpeculation() OVERRIDE; - virtual bool WasEverUsed() const OVERRIDE; - virtual bool UsingTCPFastOpen() const OVERRIDE; - virtual int64 NumBytesRead() const OVERRIDE; - virtual base::TimeDelta GetConnectTimeMicros() const OVERRIDE; - virtual bool WasNpnNegotiated() const OVERRIDE; - virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE; - virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE; - - private: - // Proxy resolution and connection functions. - void ProcessProxyResolveDone(int status); - void ProcessConnectDone(int status); - - void CloseTransportSocket(); - void RunUserConnectCallback(int status); - int ReconsiderProxyAfterError(int error); - void ReportSuccessfulProxyConnection(); - - // Callbacks passed to net APIs. - net::CompletionCallback proxy_resolve_callback_; - net::CompletionCallback connect_callback_; - - scoped_refptr<net::HttpNetworkSession> network_session_; - - // The transport socket. - scoped_ptr<net::ClientSocketHandle> transport_; - - const net::SSLConfig ssl_config_; - net::ProxyService::PacRequest* pac_request_; - net::ProxyInfo proxy_info_; - net::HostPortPair dest_host_port_pair_; - bool tried_direct_connect_fallback_; - net::BoundNetLog bound_net_log_; - base::WeakPtrFactory<ProxyResolvingClientSocket> weak_factory_; - - // The callback passed to Connect(). - net::CompletionCallback user_connect_callback_; -}; - -} // namespace notifier - -#endif // JINGLE_NOTIFIER_BASE_PROXY_RESOLVING_CLIENT_SOCKET_H_ diff --git a/jingle/notifier/base/proxy_resolving_client_socket_unittest.cc b/jingle/notifier/base/proxy_resolving_client_socket_unittest.cc deleted file mode 100644 index f856ac8..0000000 --- a/jingle/notifier/base/proxy_resolving_client_socket_unittest.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/proxy_resolving_client_socket.h" - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "net/base/mock_host_resolver.h" -#include "net/base/test_completion_callback.h" -#include "net/proxy/proxy_service.h" -#include "net/socket/socket_test_util.h" -#include "net/url_request/url_request_context_getter.h" -#include "net/url_request/url_request_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -class MyTestURLRequestContext : public TestURLRequestContext { - public: - MyTestURLRequestContext() : TestURLRequestContext(true) { - context_storage_.set_proxy_service( - net::ProxyService::CreateFixedFromPacResult( - "PROXY bad:99; PROXY maybe:80; DIRECT")); - Init(); - } - virtual ~MyTestURLRequestContext() {} -}; - -} // namespace - -namespace notifier { - -class ProxyResolvingClientSocketTest : public testing::Test { - protected: - ProxyResolvingClientSocketTest() - : url_request_context_getter_(new TestURLRequestContextGetter( - base::MessageLoopProxy::current(), - scoped_ptr<TestURLRequestContext>(new MyTestURLRequestContext))) {} - - virtual ~ProxyResolvingClientSocketTest() {} - - virtual void TearDown() { - // Clear out any messages posted by ProxyResolvingClientSocket's - // destructor. - message_loop_.RunAllPending(); - } - - MessageLoop message_loop_; - scoped_refptr<TestURLRequestContextGetter> url_request_context_getter_; -}; - -// TODO(sanjeevr): Fix this test on Linux. -TEST_F(ProxyResolvingClientSocketTest, DISABLED_ConnectError) { - net::HostPortPair dest("0.0.0.0", 0); - ProxyResolvingClientSocket proxy_resolving_socket( - NULL, - url_request_context_getter_, - net::SSLConfig(), - dest); - net::TestCompletionCallback callback; - int status = proxy_resolving_socket.Connect(callback.callback()); - // Connect always returns ERR_IO_PENDING because it is always asynchronous. - EXPECT_EQ(net::ERR_IO_PENDING, status); - status = callback.WaitForResult(); - // ProxyResolvingClientSocket::Connect() will always return an error of - // ERR_ADDRESS_INVALID for a 0 IP address. - EXPECT_EQ(net::ERR_ADDRESS_INVALID, status); -} - -TEST_F(ProxyResolvingClientSocketTest, ReportsBadProxies) { - net::HostPortPair dest("example.com", 443); - net::MockClientSocketFactory socket_factory; - - net::StaticSocketDataProvider socket_data1; - socket_data1.set_connect_data( - net::MockConnect(net::ASYNC, net::ERR_ADDRESS_UNREACHABLE)); - socket_factory.AddSocketDataProvider(&socket_data1); - - net::MockRead reads[] = { - net::MockRead("HTTP/1.1 200 Success\r\n\r\n") - }; - net::MockWrite writes[] = { - net::MockWrite("CONNECT example.com:443 HTTP/1.1\r\n" - "Host: example.com:443\r\n" - "Proxy-Connection: keep-alive\r\n\r\n") - }; - net::StaticSocketDataProvider socket_data2(reads, arraysize(reads), - writes, arraysize(writes)); - socket_data2.set_connect_data(net::MockConnect(net::ASYNC, net::OK)); - socket_factory.AddSocketDataProvider(&socket_data2); - - ProxyResolvingClientSocket proxy_resolving_socket( - &socket_factory, - url_request_context_getter_, - net::SSLConfig(), - dest); - - net::TestCompletionCallback callback; - int status = proxy_resolving_socket.Connect(callback.callback()); - EXPECT_EQ(net::ERR_IO_PENDING, status); - status = callback.WaitForResult(); - EXPECT_EQ(net::OK, status); - - net::URLRequestContext* context = - url_request_context_getter_->GetURLRequestContext(); - const net::ProxyRetryInfoMap& retry_info = - context->proxy_service()->proxy_retry_info(); - - EXPECT_EQ(1u, retry_info.size()); - net::ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99"); - EXPECT_TRUE(iter != retry_info.end()); -} - -// TODO(sanjeevr): Add more unit-tests. -} // namespace notifier diff --git a/jingle/notifier/base/resolving_client_socket_factory.h b/jingle/notifier/base/resolving_client_socket_factory.h deleted file mode 100644 index 7f5af1f..0000000 --- a/jingle/notifier/base/resolving_client_socket_factory.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef JINGLE_NOTIFIER_BASE_RESOLVING_CLIENT_SOCKET_FACTORY_H_ -#define JINGLE_NOTIFIER_BASE_RESOLVING_CLIENT_SOCKET_FACTORY_H_ - - -namespace net { -class ClientSocketHandle; -class HostPortPair; -class SSLClientSocket; -class StreamSocket; -} - -// TODO(sanjeevr): Move this to net/ - -namespace notifier { - -// Interface for a ClientSocketFactory that creates ClientSockets that can -// resolve host names and tunnel through proxies. -class ResolvingClientSocketFactory { - public: - virtual ~ResolvingClientSocketFactory() { } - // Method to create a transport socket using a HostPortPair. - virtual net::StreamSocket* CreateTransportClientSocket( - const net::HostPortPair& host_and_port) = 0; - - virtual net::SSLClientSocket* CreateSSLClientSocket( - net::ClientSocketHandle* transport_socket, - const net::HostPortPair& host_and_port) = 0; -}; - -} // namespace notifier - -#endif // JINGLE_NOTIFIER_BASE_RESOLVING_CLIENT_SOCKET_FACTORY_H_ diff --git a/jingle/notifier/base/xmpp_client_socket_factory.cc b/jingle/notifier/base/xmpp_client_socket_factory.cc deleted file mode 100644 index 2594084..0000000 --- a/jingle/notifier/base/xmpp_client_socket_factory.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012 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 "jingle/notifier/base/xmpp_client_socket_factory.h" - -#include "base/logging.h" -#include "jingle/notifier/base/fake_ssl_client_socket.h" -#include "jingle/notifier/base/proxy_resolving_client_socket.h" -#include "net/socket/client_socket_factory.h" -#include "net/socket/ssl_client_socket.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" - -namespace notifier { - -XmppClientSocketFactory::XmppClientSocketFactory( - net::ClientSocketFactory* client_socket_factory, - const net::SSLConfig& ssl_config, - const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, - bool use_fake_ssl_client_socket) - : client_socket_factory_(client_socket_factory), - request_context_getter_(request_context_getter), - ssl_config_(ssl_config), - use_fake_ssl_client_socket_(use_fake_ssl_client_socket) { - CHECK(client_socket_factory_); -} - -XmppClientSocketFactory::~XmppClientSocketFactory() {} - -net::StreamSocket* XmppClientSocketFactory::CreateTransportClientSocket( - const net::HostPortPair& host_and_port) { - // TODO(akalin): Use socket pools. - net::StreamSocket* transport_socket = new ProxyResolvingClientSocket( - NULL, - request_context_getter_, - ssl_config_, - host_and_port); - return (use_fake_ssl_client_socket_ ? - new FakeSSLClientSocket(transport_socket) : transport_socket); -} - -net::SSLClientSocket* XmppClientSocketFactory::CreateSSLClientSocket( - net::ClientSocketHandle* transport_socket, - const net::HostPortPair& host_and_port) { - net::SSLClientSocketContext context; - context.cert_verifier = - request_context_getter_->GetURLRequestContext()->cert_verifier(); - // TODO(rkn): context.server_bound_cert_service is NULL because the - // ServerBoundCertService class is not thread safe. - return client_socket_factory_->CreateSSLClientSocket( - transport_socket, host_and_port, ssl_config_, context); -} - - -} // namespace diff --git a/jingle/notifier/base/xmpp_client_socket_factory.h b/jingle/notifier/base/xmpp_client_socket_factory.h deleted file mode 100644 index 1d22e44..0000000 --- a/jingle/notifier/base/xmpp_client_socket_factory.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2011 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. - -#ifndef JINGLE_NOTIFIER_BASE_XMPP_CLIENT_SOCKET_FACTORY_H_ -#define JINGLE_NOTIFIER_BASE_XMPP_CLIENT_SOCKET_FACTORY_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "jingle/notifier/base/resolving_client_socket_factory.h" -#include "net/base/ssl_config_service.h" - -namespace net { -class ClientSocketFactory; -class ClientSocketHandle; -class HostPortPair; -class SSLClientSocket; -class StreamSocket; -class URLRequestContextGetter; -} - -namespace notifier { - -class XmppClientSocketFactory : public ResolvingClientSocketFactory { - public: - // Does not take ownership of |client_socket_factory|. - XmppClientSocketFactory( - net::ClientSocketFactory* client_socket_factory, - const net::SSLConfig& ssl_config, - const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, - bool use_fake_ssl_client_socket); - - virtual ~XmppClientSocketFactory(); - - // ResolvingClientSocketFactory implementation. - virtual net::StreamSocket* CreateTransportClientSocket( - const net::HostPortPair& host_and_port) OVERRIDE; - - virtual net::SSLClientSocket* CreateSSLClientSocket( - net::ClientSocketHandle* transport_socket, - const net::HostPortPair& host_and_port) OVERRIDE; - - private: - net::ClientSocketFactory* const client_socket_factory_; - scoped_refptr<net::URLRequestContextGetter> request_context_getter_; - const net::SSLConfig ssl_config_; - const bool use_fake_ssl_client_socket_; - - DISALLOW_COPY_AND_ASSIGN(XmppClientSocketFactory); -}; - -} // namespace notifier - -#endif // JINGLE_NOTIFIER_BASE_XMPP_CLIENT_SOCKET_FACTORY_H_ diff --git a/jingle/notifier/base/xmpp_connection.cc b/jingle/notifier/base/xmpp_connection.cc index 8ecdd9b..f8f83fd 100644 --- a/jingle/notifier/base/xmpp_connection.cc +++ b/jingle/notifier/base/xmpp_connection.cc @@ -8,10 +8,10 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/string_piece.h" -#include "jingle/notifier/base/chrome_async_socket.h" +#include "jingle/glue/chrome_async_socket.h" +#include "jingle/glue/xmpp_client_socket_factory.h" #include "jingle/notifier/base/task_pump.h" #include "jingle/notifier/base/weak_xmpp_client.h" -#include "jingle/notifier/base/xmpp_client_socket_factory.h" #include "net/base/ssl_config_service.h" #include "net/socket/client_socket_factory.h" #include "net/url_request/url_request_context.h" @@ -34,14 +34,14 @@ buzz::AsyncSocket* CreateSocket( // XmppSocketAdapter. const size_t kReadBufSize = 64U * 1024U; const size_t kWriteBufSize = 64U * 1024U; - XmppClientSocketFactory* const client_socket_factory = - new XmppClientSocketFactory( + jingle_glue::XmppClientSocketFactory* const client_socket_factory = + new jingle_glue::XmppClientSocketFactory( net::ClientSocketFactory::GetDefaultFactory(), ssl_config, request_context_getter, use_fake_ssl_client_socket); - return new ChromeAsyncSocket(client_socket_factory, - kReadBufSize, kWriteBufSize); + return new jingle_glue::ChromeAsyncSocket(client_socket_factory, + kReadBufSize, kWriteBufSize); } } // namespace |