Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: chrome/browser/extensions/api/sockets_tcp/sockets_tcp_api.cc

Issue 183893041: Move sockets APIs out of src/chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename api targets Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/extensions/api/sockets_tcp/sockets_tcp_api.h"
6
7 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
8 #include "chrome/browser/extensions/api/sockets_tcp/tcp_socket_event_dispatcher. h"
9 #include "chrome/common/extensions/api/sockets/sockets_manifest_data.h"
10 #include "content/public/common/socket_permission_request.h"
11 #include "net/base/net_errors.h"
12
13 using extensions::ResumableTCPSocket;
14 using extensions::api::sockets_tcp::SocketInfo;
15 using extensions::api::sockets_tcp::SocketProperties;
16
17 namespace {
18
19 const char kSocketNotFoundError[] = "Socket not found";
20 const char kPermissionError[] = "Does not have permission";
21
22 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id,
23 ResumableTCPSocket* socket) {
24 linked_ptr<SocketInfo> socket_info(new SocketInfo());
25 // This represents what we know about the socket, and does not call through
26 // to the system.
27 socket_info->socket_id = socket_id;
28 if (!socket->name().empty()) {
29 socket_info->name.reset(new std::string(socket->name()));
30 }
31 socket_info->persistent = socket->persistent();
32 if (socket->buffer_size() > 0) {
33 socket_info->buffer_size.reset(new int(socket->buffer_size()));
34 }
35 socket_info->paused = socket->paused();
36 socket_info->connected = socket->IsConnected();
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 // Grab the peer address as known by the OS. This and the call below will
47 // always succeed while the socket is connected, even if the socket has
48 // been remotely closed by the peer; only reading the socket will reveal
49 // that it should be closed locally.
50 net::IPEndPoint peerAddress;
51 if (socket->GetPeerAddress(&peerAddress)) {
52 socket_info->peer_address.reset(
53 new std::string(peerAddress.ToStringWithoutPort()));
54 socket_info->peer_port.reset(new int(peerAddress.port()));
55 }
56
57 return socket_info;
58 }
59
60 void SetSocketProperties(ResumableTCPSocket* socket,
61 SocketProperties* properties) {
62 if (properties->name.get()) {
63 socket->set_name(*properties->name.get());
64 }
65 if (properties->persistent.get()) {
66 socket->set_persistent(*properties->persistent.get());
67 }
68 if (properties->buffer_size.get()) {
69 // buffer size is validated when issuing the actual Recv operation
70 // on the socket.
71 socket->set_buffer_size(*properties->buffer_size.get());
72 }
73 }
74
75 } // namespace
76
77 namespace extensions {
78 namespace api {
79
80 using content::SocketPermissionRequest;
81
82 TCPSocketAsyncApiFunction::~TCPSocketAsyncApiFunction() {}
83
84 scoped_ptr<SocketResourceManagerInterface>
85 TCPSocketAsyncApiFunction::CreateSocketResourceManager() {
86 return scoped_ptr<SocketResourceManagerInterface>(
87 new SocketResourceManager<ResumableTCPSocket>()).Pass();
88 }
89
90 ResumableTCPSocket* TCPSocketAsyncApiFunction::GetTcpSocket(int socket_id) {
91 return static_cast<ResumableTCPSocket*>(GetSocket(socket_id));
92 }
93
94 TCPSocketExtensionWithDnsLookupFunction::
95 ~TCPSocketExtensionWithDnsLookupFunction() {}
96
97 scoped_ptr<SocketResourceManagerInterface>
98 TCPSocketExtensionWithDnsLookupFunction::CreateSocketResourceManager() {
99 return scoped_ptr<SocketResourceManagerInterface>(
100 new SocketResourceManager<ResumableTCPSocket>()).Pass();
101 }
102
103 ResumableTCPSocket* TCPSocketExtensionWithDnsLookupFunction::GetTcpSocket(
104 int socket_id) {
105 return static_cast<ResumableTCPSocket*>(GetSocket(socket_id));
106 }
107
108 SocketsTcpCreateFunction::SocketsTcpCreateFunction() {}
109
110 SocketsTcpCreateFunction::~SocketsTcpCreateFunction() {}
111
112 bool SocketsTcpCreateFunction::Prepare() {
113 params_ = sockets_tcp::Create::Params::Create(*args_);
114 EXTENSION_FUNCTION_VALIDATE(params_.get());
115 return true;
116 }
117
118 void SocketsTcpCreateFunction::Work() {
119 ResumableTCPSocket* socket = new ResumableTCPSocket(extension_->id());
120
121 sockets_tcp::SocketProperties* properties = params_.get()->properties.get();
122 if (properties) {
123 SetSocketProperties(socket, properties);
124 }
125
126 sockets_tcp::CreateInfo create_info;
127 create_info.socket_id = AddSocket(socket);
128 results_ = sockets_tcp::Create::Results::Create(create_info);
129 }
130
131 SocketsTcpUpdateFunction::SocketsTcpUpdateFunction() {}
132
133 SocketsTcpUpdateFunction::~SocketsTcpUpdateFunction() {}
134
135 bool SocketsTcpUpdateFunction::Prepare() {
136 params_ = sockets_tcp::Update::Params::Create(*args_);
137 EXTENSION_FUNCTION_VALIDATE(params_.get());
138 return true;
139 }
140
141 void SocketsTcpUpdateFunction::Work() {
142 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
143 if (!socket) {
144 error_ = kSocketNotFoundError;
145 return;
146 }
147
148 SetSocketProperties(socket, &params_.get()->properties);
149 results_ = sockets_tcp::Update::Results::Create();
150 }
151
152 SocketsTcpSetPausedFunction::SocketsTcpSetPausedFunction()
153 : socket_event_dispatcher_(NULL) {}
154
155 SocketsTcpSetPausedFunction::~SocketsTcpSetPausedFunction() {}
156
157 bool SocketsTcpSetPausedFunction::Prepare() {
158 params_ = api::sockets_tcp::SetPaused::Params::Create(*args_);
159 EXTENSION_FUNCTION_VALIDATE(params_.get());
160
161 socket_event_dispatcher_ = TCPSocketEventDispatcher::Get(browser_context());
162 DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
163 "If this assertion is failing during a test, then it is likely that "
164 "TestExtensionSystem is failing to provide an instance of "
165 "TCPSocketEventDispatcher.";
166 return socket_event_dispatcher_ != NULL;
167 }
168
169 void SocketsTcpSetPausedFunction::Work() {
170 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
171 if (!socket) {
172 error_ = kSocketNotFoundError;
173 return;
174 }
175
176 if (socket->paused() != params_->paused) {
177 socket->set_paused(params_->paused);
178 if (socket->IsConnected() && !params_->paused) {
179 socket_event_dispatcher_->OnSocketResume(extension_->id(),
180 params_->socket_id);
181 }
182 }
183
184 results_ = sockets_tcp::SetPaused::Results::Create();
185 }
186
187 SocketsTcpSetKeepAliveFunction::SocketsTcpSetKeepAliveFunction() {}
188
189 SocketsTcpSetKeepAliveFunction::~SocketsTcpSetKeepAliveFunction() {}
190
191 bool SocketsTcpSetKeepAliveFunction::Prepare() {
192 params_ = api::sockets_tcp::SetKeepAlive::Params::Create(*args_);
193 EXTENSION_FUNCTION_VALIDATE(params_.get());
194 return true;
195 }
196
197 void SocketsTcpSetKeepAliveFunction::Work() {
198 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
199 if (!socket) {
200 error_ = kSocketNotFoundError;
201 return;
202 }
203
204 int delay = params_->delay ? *params_->delay.get() : 0;
205
206 bool success = socket->SetKeepAlive(params_->enable, delay);
207 int net_result = (success ? net::OK : net::ERR_FAILED);
208 if (net_result != net::OK)
209 error_ = net::ErrorToString(net_result);
210 results_ = sockets_tcp::SetKeepAlive::Results::Create(net_result);
211 }
212
213 SocketsTcpSetNoDelayFunction::SocketsTcpSetNoDelayFunction() {}
214
215 SocketsTcpSetNoDelayFunction::~SocketsTcpSetNoDelayFunction() {}
216
217 bool SocketsTcpSetNoDelayFunction::Prepare() {
218 params_ = api::sockets_tcp::SetNoDelay::Params::Create(*args_);
219 EXTENSION_FUNCTION_VALIDATE(params_.get());
220 return true;
221 }
222
223 void SocketsTcpSetNoDelayFunction::Work() {
224 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
225 if (!socket) {
226 error_ = kSocketNotFoundError;
227 return;
228 }
229
230 bool success = socket->SetNoDelay(params_->no_delay);
231 int net_result = (success ? net::OK : net::ERR_FAILED);
232 if (net_result != net::OK)
233 error_ = net::ErrorToString(net_result);
234 results_ = sockets_tcp::SetNoDelay::Results::Create(net_result);
235 }
236
237 SocketsTcpConnectFunction::SocketsTcpConnectFunction()
238 : socket_event_dispatcher_(NULL) {}
239
240 SocketsTcpConnectFunction::~SocketsTcpConnectFunction() {}
241
242 bool SocketsTcpConnectFunction::Prepare() {
243 params_ = sockets_tcp::Connect::Params::Create(*args_);
244 EXTENSION_FUNCTION_VALIDATE(params_.get());
245
246 socket_event_dispatcher_ = TCPSocketEventDispatcher::Get(browser_context());
247 DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
248 "If this assertion is failing during a test, then it is likely that "
249 "TestExtensionSystem is failing to provide an instance of "
250 "TCPSocketEventDispatcher.";
251 return socket_event_dispatcher_ != NULL;
252 }
253
254 void SocketsTcpConnectFunction::AsyncWorkStart() {
255 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
256 if (!socket) {
257 error_ = kSocketNotFoundError;
258 AsyncWorkCompleted();
259 return;
260 }
261
262 content::SocketPermissionRequest param(
263 SocketPermissionRequest::TCP_CONNECT,
264 params_->peer_address,
265 params_->peer_port);
266 if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
267 error_ = kPermissionError;
268 AsyncWorkCompleted();
269 return;
270 }
271
272 StartDnsLookup(params_->peer_address);
273 }
274
275 void SocketsTcpConnectFunction::AfterDnsLookup(int lookup_result) {
276 if (lookup_result == net::OK) {
277 StartConnect();
278 } else {
279 OnCompleted(lookup_result);
280 }
281 }
282
283 void SocketsTcpConnectFunction::StartConnect() {
284 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
285 if (!socket) {
286 error_ = kSocketNotFoundError;
287 AsyncWorkCompleted();
288 return;
289 }
290
291 socket->Connect(resolved_address_, params_->peer_port,
292 base::Bind(&SocketsTcpConnectFunction::OnCompleted, this));
293 }
294
295 void SocketsTcpConnectFunction::OnCompleted(int net_result) {
296 if (net_result == net::OK) {
297 socket_event_dispatcher_->OnSocketConnect(extension_->id(),
298 params_->socket_id);
299 }
300
301 if (net_result != net::OK)
302 error_ = net::ErrorToString(net_result);
303 results_ = sockets_tcp::Connect::Results::Create(net_result);
304 AsyncWorkCompleted();
305 }
306
307 SocketsTcpDisconnectFunction::SocketsTcpDisconnectFunction() {}
308
309 SocketsTcpDisconnectFunction::~SocketsTcpDisconnectFunction() {}
310
311 bool SocketsTcpDisconnectFunction::Prepare() {
312 params_ = sockets_tcp::Disconnect::Params::Create(*args_);
313 EXTENSION_FUNCTION_VALIDATE(params_.get());
314 return true;
315 }
316
317 void SocketsTcpDisconnectFunction::Work() {
318 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
319 if (!socket) {
320 error_ = kSocketNotFoundError;
321 return;
322 }
323
324 socket->Disconnect();
325 results_ = sockets_tcp::Disconnect::Results::Create();
326 }
327
328 SocketsTcpSendFunction::SocketsTcpSendFunction()
329 : io_buffer_size_(0) {}
330
331 SocketsTcpSendFunction::~SocketsTcpSendFunction() {}
332
333 bool SocketsTcpSendFunction::Prepare() {
334 params_ = sockets_tcp::Send::Params::Create(*args_);
335 EXTENSION_FUNCTION_VALIDATE(params_.get());
336 io_buffer_size_ = params_->data.size();
337 io_buffer_ = new net::WrappedIOBuffer(params_->data.data());
338 return true;
339 }
340
341 void SocketsTcpSendFunction::AsyncWorkStart() {
342 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
343 if (!socket) {
344 error_ = kSocketNotFoundError;
345 AsyncWorkCompleted();
346 return;
347 }
348
349 socket->Write(io_buffer_, io_buffer_size_,
350 base::Bind(&SocketsTcpSendFunction::OnCompleted, this));
351 }
352
353 void SocketsTcpSendFunction::OnCompleted(int net_result) {
354 if (net_result >= net::OK) {
355 SetSendResult(net::OK, net_result);
356 } else {
357 SetSendResult(net_result, -1);
358 }
359 }
360
361 void SocketsTcpSendFunction::SetSendResult(int net_result, int bytes_sent) {
362 CHECK(net_result <= net::OK) << "Network status code must be <= net::OK";
363
364 sockets_tcp::SendInfo send_info;
365 send_info.result_code = net_result;
366 if (net_result == net::OK) {
367 send_info.bytes_sent.reset(new int(bytes_sent));
368 }
369
370 if (net_result != net::OK)
371 error_ = net::ErrorToString(net_result);
372 results_ = sockets_tcp::Send::Results::Create(send_info);
373 AsyncWorkCompleted();
374 }
375
376 SocketsTcpCloseFunction::SocketsTcpCloseFunction() {}
377
378 SocketsTcpCloseFunction::~SocketsTcpCloseFunction() {}
379
380 bool SocketsTcpCloseFunction::Prepare() {
381 params_ = sockets_tcp::Close::Params::Create(*args_);
382 EXTENSION_FUNCTION_VALIDATE(params_.get());
383 return true;
384 }
385
386 void SocketsTcpCloseFunction::Work() {
387 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
388 if (!socket) {
389 error_ = kSocketNotFoundError;
390 return;
391 }
392
393 RemoveSocket(params_->socket_id);
394 results_ = sockets_tcp::Close::Results::Create();
395 }
396
397 SocketsTcpGetInfoFunction::SocketsTcpGetInfoFunction() {}
398
399 SocketsTcpGetInfoFunction::~SocketsTcpGetInfoFunction() {}
400
401 bool SocketsTcpGetInfoFunction::Prepare() {
402 params_ = sockets_tcp::GetInfo::Params::Create(*args_);
403 EXTENSION_FUNCTION_VALIDATE(params_.get());
404 return true;
405 }
406
407 void SocketsTcpGetInfoFunction::Work() {
408 ResumableTCPSocket* socket = GetTcpSocket(params_->socket_id);
409 if (!socket) {
410 error_ = kSocketNotFoundError;
411 return;
412 }
413
414 linked_ptr<sockets_tcp::SocketInfo> socket_info =
415 CreateSocketInfo(params_->socket_id, socket);
416 results_ = sockets_tcp::GetInfo::Results::Create(*socket_info);
417 }
418
419 SocketsTcpGetSocketsFunction::SocketsTcpGetSocketsFunction() {}
420
421 SocketsTcpGetSocketsFunction::~SocketsTcpGetSocketsFunction() {}
422
423 bool SocketsTcpGetSocketsFunction::Prepare() {
424 return true;
425 }
426
427 void SocketsTcpGetSocketsFunction::Work() {
428 std::vector<linked_ptr<sockets_tcp::SocketInfo> > socket_infos;
429 base::hash_set<int>* resource_ids = GetSocketIds();
430 if (resource_ids != NULL) {
431 for (base::hash_set<int>::iterator it = resource_ids->begin();
432 it != resource_ids->end(); ++it) {
433 int socket_id = *it;
434 ResumableTCPSocket* socket = GetTcpSocket(socket_id);
435 if (socket) {
436 socket_infos.push_back(CreateSocketInfo(socket_id, socket));
437 }
438 }
439 }
440 results_ = sockets_tcp::GetSockets::Results::Create(socket_infos);
441 }
442
443 } // namespace api
444 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698