1 // Copyright 2013 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.
5 #include "chrome/browser/extensions/api/sockets_tcp_server/sockets_tcp_server_api.h"
7 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
8 #include "chrome/browser/extensions/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h"
9 #include "chrome/common/extensions/api/sockets/sockets_handler.h"
10 #include "chrome/common/extensions/permissions/permissions_data.h"
11 #include "chrome/common/extensions/permissions/socket_permission.h"
12 #include "content/public/common/socket_permission_request.h"
13 #include "net/base/net_errors.h"
15 using content::SocketPermissionRequest;
16 using extensions::ResumableTCPServerSocket;
17 using extensions::api::sockets_tcp_server::SocketInfo;
18 using extensions::api::sockets_tcp_server::SocketProperties;
22 const char kSocketNotFoundError[] = "Socket not found";
23 const char kPermissionError[] = "Does not have permission";
24 const int kDefaultListenBacklog = SOMAXCONN;
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
31 socket_info->socket_id = socket_id;
32 if (!socket->name().empty()) {
33 socket_info->name.reset(new std::string(socket->name()));
35 socket_info->persistent = socket->persistent();
36 socket_info->paused = socket->paused();
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()));
49 void SetSocketProperties(ResumableTCPServerSocket* socket,
50 SocketProperties* properties) {
51 if (properties->name.get()) {
52 socket->set_name(*properties->name.get());
54 if (properties->persistent.get()) {
55 socket->set_persistent(*properties->persistent.get());
61 namespace extensions {
64 TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {}
66 scoped_ptr<SocketResourceManagerInterface>
67 TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() {
68 return scoped_ptr<SocketResourceManagerInterface>(
69 new SocketResourceManager<ResumableTCPServerSocket>()).Pass();
72 ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket(
74 return static_cast<ResumableTCPServerSocket*>(GetSocket(socket_id));
77 SocketsTcpServerCreateFunction::SocketsTcpServerCreateFunction() {}
79 SocketsTcpServerCreateFunction::~SocketsTcpServerCreateFunction() {}
81 bool SocketsTcpServerCreateFunction::Prepare() {
82 params_ = sockets_tcp_server::Create::Params::Create(*args_);
83 EXTENSION_FUNCTION_VALIDATE(params_.get());
87 void SocketsTcpServerCreateFunction::Work() {
88 ResumableTCPServerSocket* socket =
89 new ResumableTCPServerSocket(extension_->id());
91 sockets_tcp_server::SocketProperties* properties =
92 params_.get()->properties.get();
94 SetSocketProperties(socket, properties);
97 sockets_tcp_server::CreateInfo create_info;
98 create_info.socket_id = AddSocket(socket);
99 results_ = sockets_tcp_server::Create::Results::Create(create_info);
102 SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {}
104 SocketsTcpServerUpdateFunction::~SocketsTcpServerUpdateFunction() {}
106 bool SocketsTcpServerUpdateFunction::Prepare() {
107 params_ = sockets_tcp_server::Update::Params::Create(*args_);
108 EXTENSION_FUNCTION_VALIDATE(params_.get());
112 void SocketsTcpServerUpdateFunction::Work() {
113 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
115 error_ = kSocketNotFoundError;
119 SetSocketProperties(socket, ¶ms_.get()->properties);
120 results_ = sockets_tcp_server::Update::Results::Create();
123 SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction()
124 : socket_event_dispatcher_(NULL) {}
126 SocketsTcpServerSetPausedFunction::~SocketsTcpServerSetPausedFunction() {}
128 bool SocketsTcpServerSetPausedFunction::Prepare() {
129 params_ = api::sockets_tcp_server::SetPaused::Params::Create(*args_);
130 EXTENSION_FUNCTION_VALIDATE(params_.get());
132 socket_event_dispatcher_ = TCPServerSocketEventDispatcher::Get(GetProfile());
133 DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
134 "If this assertion is failing during a test, then it is likely that "
135 "TestExtensionSystem is failing to provide an instance of "
136 "TCPServerSocketEventDispatcher.";
137 return socket_event_dispatcher_ != NULL;
140 void SocketsTcpServerSetPausedFunction::Work() {
141 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
143 error_ = kSocketNotFoundError;
147 if (socket->paused() != params_->paused) {
148 socket->set_paused(params_->paused);
149 if (socket->IsConnected() && !params_->paused) {
150 socket_event_dispatcher_->OnServerSocketResume(extension_->id(),
155 results_ = sockets_tcp_server::SetPaused::Results::Create();
158 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
159 : socket_event_dispatcher_(NULL) {}
161 SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {}
163 bool SocketsTcpServerListenFunction::Prepare() {
164 params_ = api::sockets_tcp_server::Listen::Params::Create(*args_);
165 EXTENSION_FUNCTION_VALIDATE(params_.get());
167 socket_event_dispatcher_ = TCPServerSocketEventDispatcher::Get(GetProfile());
168 DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
169 "If this assertion is failing during a test, then it is likely that "
170 "TestExtensionSystem is failing to provide an instance of "
171 "TCPServerSocketEventDispatcher.";
172 return socket_event_dispatcher_ != NULL;
175 void SocketsTcpServerListenFunction::Work() {
176 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
178 error_ = kSocketNotFoundError;
182 SocketPermissionRequest param(
183 SocketPermissionRequest::TCP_LISTEN,
186 if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
187 error_ = kPermissionError;
191 int net_result = socket->Listen(
194 params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog,
197 if (net_result != net::OK)
198 error_ = net::ErrorToString(net_result);
201 if (net_result == net::OK) {
202 socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
206 results_ = sockets_tcp_server::Listen::Results::Create(net_result);
209 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
211 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
213 bool SocketsTcpServerDisconnectFunction::Prepare() {
214 params_ = sockets_tcp_server::Disconnect::Params::Create(*args_);
215 EXTENSION_FUNCTION_VALIDATE(params_.get());
219 void SocketsTcpServerDisconnectFunction::Work() {
220 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
222 error_ = kSocketNotFoundError;
226 socket->Disconnect();
227 results_ = sockets_tcp_server::Disconnect::Results::Create();
230 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
232 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
234 bool SocketsTcpServerCloseFunction::Prepare() {
235 params_ = sockets_tcp_server::Close::Params::Create(*args_);
236 EXTENSION_FUNCTION_VALIDATE(params_.get());
240 void SocketsTcpServerCloseFunction::Work() {
241 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
243 error_ = kSocketNotFoundError;
247 RemoveSocket(params_->socket_id);
248 results_ = sockets_tcp_server::Close::Results::Create();
251 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
253 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
255 bool SocketsTcpServerGetInfoFunction::Prepare() {
256 params_ = sockets_tcp_server::GetInfo::Params::Create(*args_);
257 EXTENSION_FUNCTION_VALIDATE(params_.get());
261 void SocketsTcpServerGetInfoFunction::Work() {
262 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
264 error_ = kSocketNotFoundError;
268 linked_ptr<sockets_tcp_server::SocketInfo> socket_info =
269 CreateSocketInfo(params_->socket_id, socket);
270 results_ = sockets_tcp_server::GetInfo::Results::Create(*socket_info);
273 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
275 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
277 bool SocketsTcpServerGetSocketsFunction::Prepare() {
281 void SocketsTcpServerGetSocketsFunction::Work() {
282 std::vector<linked_ptr<sockets_tcp_server::SocketInfo> > socket_infos;
283 base::hash_set<int>* resource_ids = GetSocketIds();
284 if (resource_ids != NULL) {
285 for (base::hash_set<int>::iterator it = resource_ids->begin();
286 it != resource_ids->end(); ++it) {
288 ResumableTCPServerSocket* socket = GetTcpSocket(socket_id);
290 socket_infos.push_back(CreateSocketInfo(socket_id, socket));
294 results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
298 } // namespace extensions