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

Unified Diff: jingle/notifier/base/chrome_async_socket.cc

Issue 10817013: Move ChromeAsyncSocket to jingle/glue (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « jingle/notifier/base/chrome_async_socket.h ('k') | jingle/notifier/base/chrome_async_socket_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: jingle/notifier/base/chrome_async_socket.cc
diff --git a/jingle/notifier/base/chrome_async_socket.cc b/jingle/notifier/base/chrome_async_socket.cc
deleted file mode 100644
index ca2fde4c01a6389df3eb2791267d99f25416aacc..0000000000000000000000000000000000000000
--- 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
« no previous file with comments | « jingle/notifier/base/chrome_async_socket.h ('k') | jingle/notifier/base/chrome_async_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698