Implementation of leveldb-backed PrefStore.
[chromium-blink-merge.git] / extensions / browser / api / sockets_tcp_server / sockets_tcp_server_api.cc
blob2b7401b458fc6a3b981dcaff4ad81b8bfddaec17
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;
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 core_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_ = 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);
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_ = 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);
181 if (!socket) {
182 error_ = kSocketNotFoundError;
183 return;
186 SocketPermissionRequest param(
187 SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port);
188 if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
189 error_ = kPermissionError;
190 return;
193 int net_result = socket->Listen(
194 params_->address,
195 params_->port,
196 params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog,
197 &error_);
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(),
204 params_->socket_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());
217 return true;
220 void SocketsTcpServerDisconnectFunction::Work() {
221 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
222 if (!socket) {
223 error_ = kSocketNotFoundError;
224 return;
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());
238 return true;
241 void SocketsTcpServerCloseFunction::Work() {
242 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
243 if (!socket) {
244 error_ = kSocketNotFoundError;
245 return;
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());
259 return true;
262 void SocketsTcpServerGetInfoFunction::Work() {
263 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
264 if (!socket) {
265 error_ = kSocketNotFoundError;
266 return;
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();
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));
294 results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
297 } // namespace core_api
298 } // namespace extensions