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::core_api::sockets_tcp_server::SocketInfo
;
18 using extensions::core_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_
= core_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
);
145 error_
= kSocketNotFoundError
;
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(),
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_
= core_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::Work() {
180 ResumableTCPServerSocket
* socket
= GetTcpSocket(params_
->socket_id
);
182 error_
= kSocketNotFoundError
;
186 SocketPermissionRequest
param(
187 SocketPermissionRequest::TCP_LISTEN
, params_
->address
, params_
->port
);
188 if (!SocketsManifestData::CheckRequest(GetExtension(), param
)) {
189 error_
= kPermissionError
;
193 int net_result
= socket
->Listen(
196 params_
->backlog
.get() ? *params_
->backlog
.get() : kDefaultListenBacklog
,
199 if (net_result
!= net::OK
)
200 error_
= net::ErrorToString(net_result
);
202 if (net_result
== net::OK
) {
203 socket_event_dispatcher_
->OnServerSocketListen(extension_
->id(),
207 results_
= sockets_tcp_server::Listen::Results::Create(net_result
);
210 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
212 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
214 bool SocketsTcpServerDisconnectFunction::Prepare() {
215 params_
= sockets_tcp_server::Disconnect::Params::Create(*args_
);
216 EXTENSION_FUNCTION_VALIDATE(params_
.get());
220 void SocketsTcpServerDisconnectFunction::Work() {
221 ResumableTCPServerSocket
* socket
= GetTcpSocket(params_
->socket_id
);
223 error_
= kSocketNotFoundError
;
227 socket
->Disconnect();
228 results_
= sockets_tcp_server::Disconnect::Results::Create();
231 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
233 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
235 bool SocketsTcpServerCloseFunction::Prepare() {
236 params_
= sockets_tcp_server::Close::Params::Create(*args_
);
237 EXTENSION_FUNCTION_VALIDATE(params_
.get());
241 void SocketsTcpServerCloseFunction::Work() {
242 ResumableTCPServerSocket
* socket
= GetTcpSocket(params_
->socket_id
);
244 error_
= kSocketNotFoundError
;
248 RemoveSocket(params_
->socket_id
);
249 results_
= sockets_tcp_server::Close::Results::Create();
252 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
254 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
256 bool SocketsTcpServerGetInfoFunction::Prepare() {
257 params_
= sockets_tcp_server::GetInfo::Params::Create(*args_
);
258 EXTENSION_FUNCTION_VALIDATE(params_
.get());
262 void SocketsTcpServerGetInfoFunction::Work() {
263 ResumableTCPServerSocket
* socket
= GetTcpSocket(params_
->socket_id
);
265 error_
= kSocketNotFoundError
;
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
);
274 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
276 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
278 bool SocketsTcpServerGetSocketsFunction::Prepare() { return true; }
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();
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
);
297 } // namespace core_api
298 } // namespace extensions