Index: content/browser/devtools/tethering_handler.cc |
diff --git a/content/browser/devtools/tethering_handler.cc b/content/browser/devtools/tethering_handler.cc |
deleted file mode 100644 |
index 5f039117ff4206c1913d195d1442604fc36cfa2d..0000000000000000000000000000000000000000 |
--- a/content/browser/devtools/tethering_handler.cc |
+++ /dev/null |
@@ -1,440 +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 "content/browser/devtools/tethering_handler.h" |
- |
-#include "base/bind.h" |
-#include "base/callback.h" |
-#include "base/stl_util.h" |
-#include "base/values.h" |
-#include "content/browser/devtools/devtools_http_handler_impl.h" |
-#include "content/browser/devtools/devtools_protocol_constants.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/devtools_http_handler_delegate.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/ip_endpoint.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/net_log.h" |
-#include "net/socket/server_socket.h" |
-#include "net/socket/stream_socket.h" |
-#include "net/socket/tcp_server_socket.h" |
- |
-namespace content { |
- |
-namespace { |
- |
-const char kLocalhost[] = "127.0.0.1"; |
- |
-const int kListenBacklog = 5; |
-const int kBufferSize = 16 * 1024; |
- |
-const int kMinTetheringPort = 1024; |
-const int kMaxTetheringPort = 32767; |
- |
-class SocketPump { |
- public: |
- SocketPump(DevToolsHttpHandlerDelegate* delegate, |
- net::StreamSocket* client_socket) |
- : client_socket_(client_socket), |
- delegate_(delegate), |
- pending_writes_(0), |
- pending_destruction_(false) { |
- } |
- |
- std::string Init() { |
- std::string channel_name; |
- server_socket_ = delegate_->CreateSocketForTethering(&channel_name); |
- if (!server_socket_.get() || channel_name.empty()) |
- SelfDestruct(); |
- |
- int result = server_socket_->Accept( |
- &accepted_socket_, |
- base::Bind(&SocketPump::OnAccepted, base::Unretained(this))); |
- if (result != net::ERR_IO_PENDING) |
- OnAccepted(result); |
- return channel_name; |
- } |
- |
- private: |
- void OnAccepted(int result) { |
- if (result < 0) { |
- SelfDestruct(); |
- return; |
- } |
- |
- ++pending_writes_; // avoid SelfDestruct in first Pump |
- Pump(client_socket_.get(), accepted_socket_.get()); |
- --pending_writes_; |
- if (pending_destruction_) { |
- SelfDestruct(); |
- } else { |
- Pump(accepted_socket_.get(), client_socket_.get()); |
- } |
- } |
- |
- void Pump(net::StreamSocket* from, net::StreamSocket* to) { |
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize); |
- int result = from->Read( |
- buffer.get(), |
- kBufferSize, |
- base::Bind( |
- &SocketPump::OnRead, base::Unretained(this), from, to, buffer)); |
- if (result != net::ERR_IO_PENDING) |
- OnRead(from, to, buffer, result); |
- } |
- |
- void OnRead(net::StreamSocket* from, |
- net::StreamSocket* to, |
- scoped_refptr<net::IOBuffer> buffer, |
- int result) { |
- if (result <= 0) { |
- SelfDestruct(); |
- return; |
- } |
- |
- int total = result; |
- scoped_refptr<net::DrainableIOBuffer> drainable = |
- new net::DrainableIOBuffer(buffer.get(), total); |
- |
- ++pending_writes_; |
- result = to->Write(drainable.get(), |
- total, |
- base::Bind(&SocketPump::OnWritten, |
- base::Unretained(this), |
- drainable, |
- from, |
- to)); |
- if (result != net::ERR_IO_PENDING) |
- OnWritten(drainable, from, to, result); |
- } |
- |
- void OnWritten(scoped_refptr<net::DrainableIOBuffer> drainable, |
- net::StreamSocket* from, |
- net::StreamSocket* to, |
- int result) { |
- --pending_writes_; |
- if (result < 0) { |
- SelfDestruct(); |
- return; |
- } |
- |
- drainable->DidConsume(result); |
- if (drainable->BytesRemaining() > 0) { |
- ++pending_writes_; |
- result = to->Write(drainable.get(), |
- drainable->BytesRemaining(), |
- base::Bind(&SocketPump::OnWritten, |
- base::Unretained(this), |
- drainable, |
- from, |
- to)); |
- if (result != net::ERR_IO_PENDING) |
- OnWritten(drainable, from, to, result); |
- return; |
- } |
- |
- if (pending_destruction_) { |
- SelfDestruct(); |
- return; |
- } |
- Pump(from, to); |
- } |
- |
- void SelfDestruct() { |
- if (pending_writes_ > 0) { |
- pending_destruction_ = true; |
- return; |
- } |
- delete this; |
- } |
- |
- |
- private: |
- scoped_ptr<net::StreamSocket> client_socket_; |
- scoped_ptr<net::ServerSocket> server_socket_; |
- scoped_ptr<net::StreamSocket> accepted_socket_; |
- DevToolsHttpHandlerDelegate* delegate_; |
- int pending_writes_; |
- bool pending_destruction_; |
-}; |
- |
-static int GetPort(scoped_refptr<DevToolsProtocol::Command> command, |
- const std::string& paramName) { |
- base::DictionaryValue* params = command->params(); |
- int port = 0; |
- if (!params || |
- !params->GetInteger(paramName, &port) || |
- port < kMinTetheringPort || port > kMaxTetheringPort) |
- return 0; |
- return port; |
-} |
- |
-class BoundSocket { |
- public: |
- typedef base::Callback<void(int, const std::string&)> AcceptedCallback; |
- |
- BoundSocket(AcceptedCallback accepted_callback, |
- DevToolsHttpHandlerDelegate* delegate) |
- : accepted_callback_(accepted_callback), |
- delegate_(delegate), |
- socket_(new net::TCPServerSocket(NULL, net::NetLog::Source())), |
- port_(0) { |
- } |
- |
- virtual ~BoundSocket() { |
- } |
- |
- bool Listen(int port) { |
- port_ = port; |
- net::IPAddressNumber ip_number; |
- if (!net::ParseIPLiteralToNumber(kLocalhost, &ip_number)) |
- return false; |
- |
- net::IPEndPoint end_point(ip_number, port); |
- int result = socket_->Listen(end_point, kListenBacklog); |
- if (result < 0) |
- return false; |
- |
- net::IPEndPoint local_address; |
- result = socket_->GetLocalAddress(&local_address); |
- if (result < 0) |
- return false; |
- |
- DoAccept(); |
- return true; |
- } |
- |
- private: |
- typedef std::map<net::IPEndPoint, net::StreamSocket*> AcceptedSocketsMap; |
- |
- void DoAccept() { |
- while (true) { |
- int result = socket_->Accept( |
- &accept_socket_, |
- base::Bind(&BoundSocket::OnAccepted, base::Unretained(this))); |
- if (result == net::ERR_IO_PENDING) |
- break; |
- else |
- HandleAcceptResult(result); |
- } |
- } |
- |
- void OnAccepted(int result) { |
- HandleAcceptResult(result); |
- if (result == net::OK) |
- DoAccept(); |
- } |
- |
- void HandleAcceptResult(int result) { |
- if (result != net::OK) |
- return; |
- |
- SocketPump* pump = new SocketPump(delegate_, accept_socket_.release()); |
- std::string name = pump->Init(); |
- if (!name.empty()) |
- accepted_callback_.Run(port_, name); |
- } |
- |
- AcceptedCallback accepted_callback_; |
- DevToolsHttpHandlerDelegate* delegate_; |
- scoped_ptr<net::ServerSocket> socket_; |
- scoped_ptr<net::StreamSocket> accept_socket_; |
- int port_; |
-}; |
- |
-} // namespace |
- |
-// TetheringHandler::TetheringImpl ------------------------------------------- |
- |
-class TetheringHandler::TetheringImpl { |
- public: |
- TetheringImpl( |
- base::WeakPtr<TetheringHandler> handler, |
- DevToolsHttpHandlerDelegate* delegate); |
- ~TetheringImpl(); |
- |
- void Bind(scoped_refptr<DevToolsProtocol::Command> command, int port); |
- void Unbind(scoped_refptr<DevToolsProtocol::Command> command, int port); |
- void Accepted(int port, const std::string& name); |
- |
- private: |
- void SendInternalError(scoped_refptr<DevToolsProtocol::Command> command, |
- const std::string& message); |
- |
- base::WeakPtr<TetheringHandler> handler_; |
- DevToolsHttpHandlerDelegate* delegate_; |
- |
- typedef std::map<int, BoundSocket*> BoundSockets; |
- BoundSockets bound_sockets_; |
-}; |
- |
-TetheringHandler::TetheringImpl::TetheringImpl( |
- base::WeakPtr<TetheringHandler> handler, |
- DevToolsHttpHandlerDelegate* delegate) |
- : handler_(handler), |
- delegate_(delegate) { |
-} |
- |
-TetheringHandler::TetheringImpl::~TetheringImpl() { |
- STLDeleteContainerPairSecondPointers(bound_sockets_.begin(), |
- bound_sockets_.end()); |
-} |
- |
-void TetheringHandler::TetheringImpl::Bind( |
- scoped_refptr<DevToolsProtocol::Command> command, int port) { |
- if (bound_sockets_.find(port) != bound_sockets_.end()) { |
- SendInternalError(command, "Port already bound"); |
- return; |
- } |
- |
- BoundSocket::AcceptedCallback callback = base::Bind( |
- &TetheringHandler::TetheringImpl::Accepted, base::Unretained(this)); |
- scoped_ptr<BoundSocket> bound_socket(new BoundSocket(callback, delegate_)); |
- if (!bound_socket->Listen(port)) { |
- SendInternalError(command, "Could not bind port"); |
- return; |
- } |
- |
- bound_sockets_[port] = bound_socket.release(); |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&TetheringHandler::SendBindSuccess, handler_, command)); |
-} |
- |
-void TetheringHandler::TetheringImpl::Unbind( |
- scoped_refptr<DevToolsProtocol::Command> command, int port) { |
- |
- BoundSockets::iterator it = bound_sockets_.find(port); |
- if (it == bound_sockets_.end()) { |
- SendInternalError(command, "Port is not bound"); |
- return; |
- } |
- |
- delete it->second; |
- bound_sockets_.erase(it); |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&TetheringHandler::SendUnbindSuccess, handler_, command)); |
-} |
- |
-void TetheringHandler::TetheringImpl::Accepted( |
- int port, const std::string& name) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&TetheringHandler::Accepted, handler_, port, name)); |
-} |
- |
-void TetheringHandler::TetheringImpl::SendInternalError( |
- scoped_refptr<DevToolsProtocol::Command> command, |
- const std::string& message) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&TetheringHandler::SendInternalError, handler_, |
- command, message)); |
-} |
- |
- |
-// TetheringHandler ---------------------------------------------------------- |
- |
-// static |
-TetheringHandler::TetheringImpl* TetheringHandler::impl_ = nullptr; |
- |
-TetheringHandler::TetheringHandler( |
- DevToolsHttpHandlerDelegate* delegate, |
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy) |
- : delegate_(delegate), |
- message_loop_proxy_(message_loop_proxy), |
- is_active_(false), |
- weak_factory_(this) { |
- RegisterCommandHandler(devtools::Tethering::bind::kName, |
- base::Bind(&TetheringHandler::OnBind, |
- base::Unretained(this))); |
- RegisterCommandHandler(devtools::Tethering::unbind::kName, |
- base::Bind(&TetheringHandler::OnUnbind, |
- base::Unretained(this))); |
-} |
- |
-TetheringHandler::~TetheringHandler() { |
- if (is_active_) { |
- message_loop_proxy_->DeleteSoon(FROM_HERE, impl_); |
- impl_ = nullptr; |
- } |
-} |
- |
-void TetheringHandler::Accepted(int port, const std::string& name) { |
- base::DictionaryValue* params = new base::DictionaryValue(); |
- params->SetInteger(devtools::Tethering::accepted::kParamPort, port); |
- params->SetString(devtools::Tethering::accepted::kParamConnectionId, name); |
- SendNotification(devtools::Tethering::accepted::kName, params); |
-} |
- |
-bool TetheringHandler::Activate() { |
- if (is_active_) |
- return true; |
- if (impl_) |
- return false; |
- is_active_ = true; |
- impl_ = new TetheringImpl(weak_factory_.GetWeakPtr(), delegate_); |
- return true; |
-} |
- |
-scoped_refptr<DevToolsProtocol::Response> |
-TetheringHandler::OnBind(scoped_refptr<DevToolsProtocol::Command> command) { |
- const std::string& portParamName = devtools::Tethering::bind::kParamPort; |
- int port = GetPort(command, portParamName); |
- if (port == 0) |
- return command->InvalidParamResponse(portParamName); |
- |
- if (!Activate()) { |
- return command->ServerErrorResponse( |
- "Tethering is used by another connection"); |
- } |
- DCHECK(impl_); |
- message_loop_proxy_->PostTask( |
- FROM_HERE, |
- base::Bind(&TetheringImpl::Bind, base::Unretained(impl_), |
- command, port)); |
- return command->AsyncResponsePromise(); |
-} |
- |
-scoped_refptr<DevToolsProtocol::Response> |
-TetheringHandler::OnUnbind(scoped_refptr<DevToolsProtocol::Command> command) { |
- const std::string& portParamName = devtools::Tethering::unbind::kParamPort; |
- int port = GetPort(command, portParamName); |
- if (port == 0) |
- return command->InvalidParamResponse(portParamName); |
- |
- if (!Activate()) { |
- return command->ServerErrorResponse( |
- "Tethering is used by another connection"); |
- } |
- DCHECK(impl_); |
- message_loop_proxy_->PostTask( |
- FROM_HERE, |
- base::Bind(&TetheringImpl::Unbind, base::Unretained(impl_), |
- command, port)); |
- return command->AsyncResponsePromise(); |
-} |
- |
-void TetheringHandler::SendBindSuccess( |
- scoped_refptr<DevToolsProtocol::Command> command) { |
- SendAsyncResponse(command->SuccessResponse(nullptr)); |
-} |
- |
-void TetheringHandler::SendUnbindSuccess( |
- scoped_refptr<DevToolsProtocol::Command> command) { |
- SendAsyncResponse(command->SuccessResponse(nullptr)); |
-} |
- |
-void TetheringHandler::SendInternalError( |
- scoped_refptr<DevToolsProtocol::Command> command, |
- const std::string& message) { |
- SendAsyncResponse(command->InternalErrorResponse(message)); |
-} |
- |
-} // namespace content |