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 |