Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / extensions / browser / api / sockets_tcp_server / sockets_tcp_server_api.cc
blob24fad16ca2bc537e0d4886a63a0671b9b935eaca
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.
5 #include "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h"
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"
15 using content::SocketPermissionRequest;
16 using extensions::ResumableTCPServerSocket;
17 using extensions::api::sockets_tcp_server::SocketInfo;
18 using extensions::api::sockets_tcp_server::SocketProperties;
20 namespace {
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
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()));
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()));
46 return socket_info;
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());
59 } // namespace
61 namespace extensions {
62 namespace api {
64 TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {}
66 scoped_ptr<SocketResourceManagerInterface>
67 TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() {
68 return scoped_ptr<SocketResourceManagerInterface>(
69 new SocketResourceManager<ResumableTCPServerSocket>()).Pass();
72 ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket(
73 int socket_id) {
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());
84 return true;
87 void SocketsTcpServerCreateFunction::Work() {
88 ResumableTCPServerSocket* socket =
89 new ResumableTCPServerSocket(extension_->id());
91 sockets_tcp_server::SocketProperties* properties =
92 params_.get()->properties.get();
93 if (properties) {
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());
109 return true;
112 void SocketsTcpServerUpdateFunction::Work() {
113 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
114 if (!socket) {
115 error_ = kSocketNotFoundError;
116 return;
119 SetSocketProperties(socket, &params_.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_ =
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;
142 void SocketsTcpServerSetPausedFunction::Work() {
143 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
144 if (!socket) {
145 error_ = kSocketNotFoundError;
146 return;
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);
157 results_ = sockets_tcp_server::SetPaused::Results::Create();
160 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
161 : socket_event_dispatcher_(NULL) {}
163 SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {}
165 bool SocketsTcpServerListenFunction::Prepare() {
166 params_ = api::sockets_tcp_server::Listen::Params::Create(*args_);
167 EXTENSION_FUNCTION_VALIDATE(params_.get());
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;
179 void SocketsTcpServerListenFunction::AsyncWorkStart() {
180 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
181 if (!socket) {
182 error_ = kSocketNotFoundError;
183 AsyncWorkCompleted();
184 return;
187 SocketPermissionRequest param(
188 SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port);
189 if (!SocketsManifestData::CheckRequest(extension(), param)) {
190 error_ = kPermissionError;
191 AsyncWorkCompleted();
192 return;
195 int net_result = socket->Listen(
196 params_->address,
197 params_->port,
198 params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog,
199 &error_);
200 results_ = sockets_tcp_server::Listen::Results::Create(net_result);
201 if (net_result == net::OK) {
202 socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
203 params_->socket_id);
204 } else {
205 error_ = net::ErrorToString(net_result);
206 AsyncWorkCompleted();
207 return;
210 OpenFirewallHole(params_->address, params_->socket_id, socket);
213 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
215 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
217 bool SocketsTcpServerDisconnectFunction::Prepare() {
218 params_ = sockets_tcp_server::Disconnect::Params::Create(*args_);
219 EXTENSION_FUNCTION_VALIDATE(params_.get());
220 return true;
223 void SocketsTcpServerDisconnectFunction::Work() {
224 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
225 if (!socket) {
226 error_ = kSocketNotFoundError;
227 return;
230 socket->Disconnect();
231 results_ = sockets_tcp_server::Disconnect::Results::Create();
234 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
236 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
238 bool SocketsTcpServerCloseFunction::Prepare() {
239 params_ = sockets_tcp_server::Close::Params::Create(*args_);
240 EXTENSION_FUNCTION_VALIDATE(params_.get());
241 return true;
244 void SocketsTcpServerCloseFunction::Work() {
245 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
246 if (!socket) {
247 error_ = kSocketNotFoundError;
248 return;
251 RemoveSocket(params_->socket_id);
252 results_ = sockets_tcp_server::Close::Results::Create();
255 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
257 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
259 bool SocketsTcpServerGetInfoFunction::Prepare() {
260 params_ = sockets_tcp_server::GetInfo::Params::Create(*args_);
261 EXTENSION_FUNCTION_VALIDATE(params_.get());
262 return true;
265 void SocketsTcpServerGetInfoFunction::Work() {
266 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
267 if (!socket) {
268 error_ = kSocketNotFoundError;
269 return;
272 linked_ptr<sockets_tcp_server::SocketInfo> socket_info =
273 CreateSocketInfo(params_->socket_id, socket);
274 results_ = sockets_tcp_server::GetInfo::Results::Create(*socket_info);
277 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
279 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
281 bool SocketsTcpServerGetSocketsFunction::Prepare() { return true; }
283 void SocketsTcpServerGetSocketsFunction::Work() {
284 std::vector<linked_ptr<sockets_tcp_server::SocketInfo> > socket_infos;
285 base::hash_set<int>* resource_ids = GetSocketIds();
286 if (resource_ids != NULL) {
287 for (base::hash_set<int>::iterator it = resource_ids->begin();
288 it != resource_ids->end();
289 ++it) {
290 int socket_id = *it;
291 ResumableTCPServerSocket* socket = GetTcpSocket(socket_id);
292 if (socket) {
293 socket_infos.push_back(CreateSocketInfo(socket_id, socket));
297 results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
300 } // namespace api
301 } // namespace extensions