Chromium Code Reviews| Index: chrome/browser/extensions/api/socket/tls_socket.cc |
| diff --git a/chrome/browser/extensions/api/socket/tls_socket.cc b/chrome/browser/extensions/api/socket/tls_socket.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..463ce095f7169156053d97af7155d85d177f2186 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/api/socket/tls_socket.cc |
| @@ -0,0 +1,143 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/extensions/api/socket/tls_socket.h" |
| + |
| +#include "base/logging.h" |
| +#include "chrome/browser/extensions/api/api_resource.h" |
| +#include "net/base/address_list.h" |
| +#include "net/base/ip_endpoint.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/base/rand_callback.h" |
| +#include "net/socket/tcp_client_socket.h" |
| + |
| +namespace extensions { |
| + |
| +const char kTLSSocketTypeInvalidError[] = |
| + "Cannot listen on a socket that's already connected."; |
| + |
| +TLSSocket::TLSSocket(net::StreamSocket* tls_socket, |
| + net::TCPClientSocket* underlying_tcp_socket, |
| + const std::string& owner_extension_id) |
| + : Socket(owner_extension_id), |
| + tls_socket_(tls_socket), |
| + underlying_socket_(underlying_tcp_socket) { |
| +} |
| + |
| +TLSSocket::~TLSSocket() { |
| + Disconnect(); |
| +} |
| + |
| +void TLSSocket::Connect(const std::string& address, |
| + int port, |
| + const CompletionCallback& callback) { |
| + callback.Run(net::ERR_CONNECTION_FAILED); |
| +} |
| + |
| +void TLSSocket::Disconnect() { |
| + if (tls_socket_) { |
| + tls_socket_->Disconnect(); |
| + tls_socket_.reset(); |
| + } |
| +} |
| + |
| +int TLSSocket::Bind(const std::string& address, int port) { |
| + return net::ERR_NOT_IMPLEMENTED; |
| +} |
| + |
| +void TLSSocket::Read(int count, |
| + const ReadCompletionCallback& callback) { |
| + DCHECK(!callback.is_null()); |
| + |
| + if (!read_callback_.is_null()) { |
| + callback.Run(net::ERR_IO_PENDING, NULL); |
| + return; |
| + } |
| + |
| + if (count <= 0) { |
| + callback.Run(net::ERR_INVALID_ARGUMENT, NULL); |
| + return; |
| + } |
| + |
| + if (!tls_socket_.get() || !IsConnected()) { |
| + callback.Run(net::ERR_SOCKET_NOT_CONNECTED, NULL); |
| + return; |
| + } |
| + |
| + read_callback_ = callback; |
| + scoped_refptr<net::IOBuffer> io_buffer = new net::IOBuffer(count); |
| + int result = tls_socket_->Read( |
| + io_buffer.get(), count, base::Bind(&TLSSocket::OnReadComplete, |
| + base::Unretained(this), |
| + io_buffer)); |
| + |
| + if (result != net::ERR_IO_PENDING) |
| + OnReadComplete(io_buffer, result); |
|
Ryan Sleevi
2013/11/25 17:30:13
This is a dangerous pattern (see comments in the T
Lally Singh
2013/12/05 17:07:12
Fair enough on both counts. The existing APIs do
|
| +} |
| + |
| +void TLSSocket::OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, |
| + int result) { |
| + DCHECK(!read_callback_.is_null()); |
| + read_callback_.Run(result, io_buffer); |
| + read_callback_.Reset(); |
| +} |
| + |
| +int TLSSocket::WriteImpl(net::IOBuffer* io_buffer, |
| + int io_buffer_size, |
| + const net::CompletionCallback& callback) { |
| + if (!IsConnected()) |
| + return net::ERR_SOCKET_NOT_CONNECTED; |
| + else |
| + return tls_socket_->Write(io_buffer, io_buffer_size, callback); |
| +} |
| + |
| +void TLSSocket::RecvFrom(int count, |
| + const RecvFromCompletionCallback& callback) { |
| + callback.Run(net::ERR_FAILED, NULL, NULL, 0); |
| +} |
| + |
| +void TLSSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer, |
| + int byte_count, |
| + const std::string& address, |
| + int port, |
| + const CompletionCallback& callback) { |
| + callback.Run(net::ERR_FAILED); |
| +} |
| + |
| +bool TLSSocket::SetKeepAlive(bool enable, int delay) { |
| + return IsConnected() && underlying_socket_->SetKeepAlive(enable, delay); |
| +} |
| + |
| +bool TLSSocket::SetNoDelay(bool no_delay) { |
| + return IsConnected() && underlying_socket_->SetNoDelay(no_delay); |
| +} |
| + |
| +int TLSSocket::Listen(const std::string& address, int port, int backlog, |
| + std::string* error_msg) { |
| + *error_msg = kTLSSocketTypeInvalidError; |
| + return net::ERR_NOT_IMPLEMENTED; |
| +} |
| + |
| +void TLSSocket::Accept(const AcceptCompletionCallback &callback) { |
| + callback.Run(net::ERR_FAILED, NULL); |
| +} |
| + |
| +bool TLSSocket::IsConnected() { |
| + return tls_socket_.get() && tls_socket_->IsConnected() && |
| + underlying_socket_.get() && underlying_socket_->IsConnected(); |
| +} |
| + |
| +bool TLSSocket::GetPeerAddress(net::IPEndPoint* address) { |
| + return IsConnected() && underlying_socket_->GetPeerAddress(address); |
| +} |
| + |
| +bool TLSSocket::GetLocalAddress(net::IPEndPoint* address) { |
| + return IsConnected() && underlying_socket_->GetLocalAddress(address); |
| +} |
| + |
| +Socket::SocketType TLSSocket::GetSocketType() const { |
| + return Socket::TYPE_TCP; |
| +} |
| + |
| +} // namespace extensions |