Home | History | Annotate | Download | only in sockets_tcp_server
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h"
      6 
      7 #include "content/public/common/socket_permission_request.h"
      8 #include "extensions/browser/api/socket/tcp_socket.h"
      9 #include "extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h"
     10 #include "extensions/common/api/sockets/sockets_manifest_data.h"
     11 #include "extensions/common/permissions/permissions_data.h"
     12 #include "extensions/common/permissions/socket_permission.h"
     13 #include "net/base/net_errors.h"
     14 
     15 using content::SocketPermissionRequest;
     16 using extensions::ResumableTCPServerSocket;
     17 using extensions::core_api::sockets_tcp_server::SocketInfo;
     18 using extensions::core_api::sockets_tcp_server::SocketProperties;
     19 
     20 namespace {
     21 
     22 const char kSocketNotFoundError[] = "Socket not found";
     23 const char kPermissionError[] = "Does not have permission";
     24 const int kDefaultListenBacklog = SOMAXCONN;
     25 
     26 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id,
     27                                         ResumableTCPServerSocket* socket) {
     28   linked_ptr<SocketInfo> socket_info(new SocketInfo());
     29   // This represents what we know about the socket, and does not call through
     30   // to the system.
     31   socket_info->socket_id = socket_id;
     32   if (!socket->name().empty()) {
     33     socket_info->name.reset(new std::string(socket->name()));
     34   }
     35   socket_info->persistent = socket->persistent();
     36   socket_info->paused = socket->paused();
     37 
     38   // Grab the local address as known by the OS.
     39   net::IPEndPoint localAddress;
     40   if (socket->GetLocalAddress(&localAddress)) {
     41     socket_info->local_address.reset(
     42         new std::string(localAddress.ToStringWithoutPort()));
     43     socket_info->local_port.reset(new int(localAddress.port()));
     44   }
     45 
     46   return socket_info;
     47 }
     48 
     49 void SetSocketProperties(ResumableTCPServerSocket* socket,
     50                          SocketProperties* properties) {
     51   if (properties->name.get()) {
     52     socket->set_name(*properties->name.get());
     53   }
     54   if (properties->persistent.get()) {
     55     socket->set_persistent(*properties->persistent.get());
     56   }
     57 }
     58 
     59 }  // namespace
     60 
     61 namespace extensions {
     62 namespace core_api {
     63 
     64 TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {}
     65 
     66 scoped_ptr<SocketResourceManagerInterface>
     67 TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() {
     68   return scoped_ptr<SocketResourceManagerInterface>(
     69              new SocketResourceManager<ResumableTCPServerSocket>()).Pass();
     70 }
     71 
     72 ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket(
     73     int socket_id) {
     74   return static_cast<ResumableTCPServerSocket*>(GetSocket(socket_id));
     75 }
     76 
     77 SocketsTcpServerCreateFunction::SocketsTcpServerCreateFunction() {}
     78 
     79 SocketsTcpServerCreateFunction::~SocketsTcpServerCreateFunction() {}
     80 
     81 bool SocketsTcpServerCreateFunction::Prepare() {
     82   params_ = sockets_tcp_server::Create::Params::Create(*args_);
     83   EXTENSION_FUNCTION_VALIDATE(params_.get());
     84   return true;
     85 }
     86 
     87 void SocketsTcpServerCreateFunction::Work() {
     88   ResumableTCPServerSocket* socket =
     89       new ResumableTCPServerSocket(extension_->id());
     90 
     91   sockets_tcp_server::SocketProperties* properties =
     92       params_.get()->properties.get();
     93   if (properties) {
     94     SetSocketProperties(socket, properties);
     95   }
     96 
     97   sockets_tcp_server::CreateInfo create_info;
     98   create_info.socket_id = AddSocket(socket);
     99   results_ = sockets_tcp_server::Create::Results::Create(create_info);
    100 }
    101 
    102 SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {}
    103 
    104 SocketsTcpServerUpdateFunction::~SocketsTcpServerUpdateFunction() {}
    105 
    106 bool SocketsTcpServerUpdateFunction::Prepare() {
    107   params_ = sockets_tcp_server::Update::Params::Create(*args_);
    108   EXTENSION_FUNCTION_VALIDATE(params_.get());
    109   return true;
    110 }
    111 
    112 void SocketsTcpServerUpdateFunction::Work() {
    113   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
    114   if (!socket) {
    115     error_ = kSocketNotFoundError;
    116     return;
    117   }
    118 
    119   SetSocketProperties(socket, &params_.get()->properties);
    120   results_ = sockets_tcp_server::Update::Results::Create();
    121 }
    122 
    123 SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction()
    124     : socket_event_dispatcher_(NULL) {}
    125 
    126 SocketsTcpServerSetPausedFunction::~SocketsTcpServerSetPausedFunction() {}
    127 
    128 bool SocketsTcpServerSetPausedFunction::Prepare() {
    129   params_ = core_api::sockets_tcp_server::SetPaused::Params::Create(*args_);
    130   EXTENSION_FUNCTION_VALIDATE(params_.get());
    131 
    132   socket_event_dispatcher_ =
    133       TCPServerSocketEventDispatcher::Get(browser_context());
    134   DCHECK(socket_event_dispatcher_)
    135       << "There is no socket event dispatcher. "
    136          "If this assertion is failing during a test, then it is likely that "
    137          "TestExtensionSystem is failing to provide an instance of "
    138          "TCPServerSocketEventDispatcher.";
    139   return socket_event_dispatcher_ != NULL;
    140 }
    141 
    142 void SocketsTcpServerSetPausedFunction::Work() {
    143   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
    144   if (!socket) {
    145     error_ = kSocketNotFoundError;
    146     return;
    147   }
    148 
    149   if (socket->paused() != params_->paused) {
    150     socket->set_paused(params_->paused);
    151     if (socket->IsConnected() && !params_->paused) {
    152       socket_event_dispatcher_->OnServerSocketResume(extension_->id(),
    153                                                      params_->socket_id);
    154     }
    155   }
    156 
    157   results_ = sockets_tcp_server::SetPaused::Results::Create();
    158 }
    159 
    160 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
    161     : socket_event_dispatcher_(NULL) {}
    162 
    163 SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {}
    164 
    165 bool SocketsTcpServerListenFunction::Prepare() {
    166   params_ = core_api::sockets_tcp_server::Listen::Params::Create(*args_);
    167   EXTENSION_FUNCTION_VALIDATE(params_.get());
    168 
    169   socket_event_dispatcher_ =
    170       TCPServerSocketEventDispatcher::Get(browser_context());
    171   DCHECK(socket_event_dispatcher_)
    172       << "There is no socket event dispatcher. "
    173          "If this assertion is failing during a test, then it is likely that "
    174          "TestExtensionSystem is failing to provide an instance of "
    175          "TCPServerSocketEventDispatcher.";
    176   return socket_event_dispatcher_ != NULL;
    177 }
    178 
    179 void SocketsTcpServerListenFunction::Work() {
    180   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
    181   if (!socket) {
    182     error_ = kSocketNotFoundError;
    183     return;
    184   }
    185 
    186   SocketPermissionRequest param(
    187       SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port);
    188   if (!SocketsManifestData::CheckRequest(extension(), param)) {
    189     error_ = kPermissionError;
    190     return;
    191   }
    192 
    193   int net_result = socket->Listen(
    194       params_->address,
    195       params_->port,
    196       params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog,
    197       &error_);
    198 
    199   if (net_result != net::OK)
    200     error_ = net::ErrorToString(net_result);
    201 
    202   if (net_result == net::OK) {
    203     socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
    204                                                    params_->socket_id);
    205   }
    206 
    207   results_ = sockets_tcp_server::Listen::Results::Create(net_result);
    208 }
    209 
    210 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
    211 
    212 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
    213 
    214 bool SocketsTcpServerDisconnectFunction::Prepare() {
    215   params_ = sockets_tcp_server::Disconnect::Params::Create(*args_);
    216   EXTENSION_FUNCTION_VALIDATE(params_.get());
    217   return true;
    218 }
    219 
    220 void SocketsTcpServerDisconnectFunction::Work() {
    221   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
    222   if (!socket) {
    223     error_ = kSocketNotFoundError;
    224     return;
    225   }
    226 
    227   socket->Disconnect();
    228   results_ = sockets_tcp_server::Disconnect::Results::Create();
    229 }
    230 
    231 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
    232 
    233 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
    234 
    235 bool SocketsTcpServerCloseFunction::Prepare() {
    236   params_ = sockets_tcp_server::Close::Params::Create(*args_);
    237   EXTENSION_FUNCTION_VALIDATE(params_.get());
    238   return true;
    239 }
    240 
    241 void SocketsTcpServerCloseFunction::Work() {
    242   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
    243   if (!socket) {
    244     error_ = kSocketNotFoundError;
    245     return;
    246   }
    247 
    248   RemoveSocket(params_->socket_id);
    249   results_ = sockets_tcp_server::Close::Results::Create();
    250 }
    251 
    252 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
    253 
    254 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
    255 
    256 bool SocketsTcpServerGetInfoFunction::Prepare() {
    257   params_ = sockets_tcp_server::GetInfo::Params::Create(*args_);
    258   EXTENSION_FUNCTION_VALIDATE(params_.get());
    259   return true;
    260 }
    261 
    262 void SocketsTcpServerGetInfoFunction::Work() {
    263   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
    264   if (!socket) {
    265     error_ = kSocketNotFoundError;
    266     return;
    267   }
    268 
    269   linked_ptr<sockets_tcp_server::SocketInfo> socket_info =
    270       CreateSocketInfo(params_->socket_id, socket);
    271   results_ = sockets_tcp_server::GetInfo::Results::Create(*socket_info);
    272 }
    273 
    274 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
    275 
    276 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
    277 
    278 bool SocketsTcpServerGetSocketsFunction::Prepare() { return true; }
    279 
    280 void SocketsTcpServerGetSocketsFunction::Work() {
    281   std::vector<linked_ptr<sockets_tcp_server::SocketInfo> > socket_infos;
    282   base::hash_set<int>* resource_ids = GetSocketIds();
    283   if (resource_ids != NULL) {
    284     for (base::hash_set<int>::iterator it = resource_ids->begin();
    285          it != resource_ids->end();
    286          ++it) {
    287       int socket_id = *it;
    288       ResumableTCPServerSocket* socket = GetTcpSocket(socket_id);
    289       if (socket) {
    290         socket_infos.push_back(CreateSocketInfo(socket_id, socket));
    291       }
    292     }
    293   }
    294   results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
    295 }
    296 
    297 }  // namespace core_api
    298 }  // namespace extensions
    299