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

Side by Side Diff: chrome/browser/extensions/api/socket/socket_api.cc

Issue 10537017: Allow hostnames in socket.connect(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mihaip's comments + clang fix. Created 8 years, 6 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/socket/socket_api.h" 5 #include "chrome/browser/extensions/api/socket/socket_api.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/extensions/api/api_resource_controller.h" 9 #include "chrome/browser/extensions/api/api_resource_controller.h"
10 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h"
9 #include "chrome/browser/extensions/api/socket/socket.h" 11 #include "chrome/browser/extensions/api/socket/socket.h"
10 #include "chrome/browser/extensions/api/socket/tcp_socket.h" 12 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
11 #include "chrome/browser/extensions/api/socket/udp_socket.h" 13 #include "chrome/browser/extensions/api/socket/udp_socket.h"
12 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/io_thread.h"
16 #include "net/base/host_port_pair.h"
13 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
14 #include "net/base/ip_endpoint.h" 18 #include "net/base/ip_endpoint.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/net_log.h"
15 21
16 namespace extensions { 22 namespace extensions {
17 23
18 const char kAddressKey[] = "address"; 24 const char kAddressKey[] = "address";
19 const char kPortKey[] = "port"; 25 const char kPortKey[] = "port";
20 const char kBytesWrittenKey[] = "bytesWritten"; 26 const char kBytesWrittenKey[] = "bytesWritten";
21 const char kDataKey[] = "data"; 27 const char kDataKey[] = "data";
22 const char kResultCodeKey[] = "resultCode"; 28 const char kResultCodeKey[] = "resultCode";
23 const char kSocketIdKey[] = "socketId"; 29 const char kSocketIdKey[] = "socketId";
24 const char kTCPOption[] = "tcp"; 30 const char kTCPOption[] = "tcp";
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 bool SocketDestroyFunction::Prepare() { 83 bool SocketDestroyFunction::Prepare() {
78 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 84 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
79 return true; 85 return true;
80 } 86 }
81 87
82 void SocketDestroyFunction::Work() { 88 void SocketDestroyFunction::Work() {
83 if (!controller()->RemoveSocket(socket_id_)) 89 if (!controller()->RemoveSocket(socket_id_))
84 error_ = kSocketNotFoundError; 90 error_ = kSocketNotFoundError;
85 } 91 }
86 92
93 SocketConnectFunction::SocketConnectFunction()
94 : io_thread_(g_browser_process->io_thread()),
95 request_handle_(new net::HostResolver::RequestHandle()),
96 addresses_(new net::AddressList) {
97 }
98
99 SocketConnectFunction::~SocketConnectFunction() {
100 }
101
87 bool SocketConnectFunction::Prepare() { 102 bool SocketConnectFunction::Prepare() {
88 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 103 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
89 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); 104 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_));
90 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); 105 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
91 return true; 106 return true;
92 } 107 }
93 108
94 void SocketConnectFunction::AsyncWorkStart() { 109 void SocketConnectFunction::AsyncWorkStart() {
110 StartDnsLookup();
111 }
112
113 void SocketConnectFunction::StartDnsLookup() {
114 net::HostResolver* host_resolver =
115 HostResolverWrapper::GetInstance()->GetHostResolver(
116 io_thread_->globals()->host_resolver.get());
117 DCHECK(host_resolver);
118
119 // Yes, we are passing zero as the port. There are some interesting but not
120 // presently relevant reasons why HostResolver asks for the port of the
121 // hostname you'd like to resolve, even though it doesn't use that value in
122 // determining its answer.
123 net::HostPortPair host_port_pair(hostname_, 0);
124
125 net::HostResolver::RequestInfo request_info(host_port_pair);
126 int resolve_result = host_resolver->Resolve(
127 request_info, addresses_.get(),
128 base::Bind(&SocketConnectFunction::OnDnsLookup, this),
129 request_handle_.get(), net::BoundNetLog());
130
131 // Balanced in OnConnect().
132 AddRef();
133
134 if (resolve_result != net::ERR_IO_PENDING)
135 OnDnsLookup(resolve_result);
136 }
137
138 void SocketConnectFunction::OnDnsLookup(int resolve_result) {
139 if (resolve_result == net::OK) {
140 DCHECK(!addresses_->empty());
141 resolved_address_ = addresses_->front().ToStringWithoutPort();
142 StartConnect();
143 } else {
144 OnConnect(resolve_result);
145 }
146 }
147
148 void SocketConnectFunction::StartConnect() {
95 Socket* socket = controller()->GetSocket(socket_id_); 149 Socket* socket = controller()->GetSocket(socket_id_);
96 if (!socket) { 150 if (!socket) {
97 error_ = kSocketNotFoundError; 151 error_ = kSocketNotFoundError;
98 OnCompleted(-1); 152 OnConnect(-1);
99 return; 153 return;
100 } 154 }
101 155
102 socket->Connect(address_, port_, 156 socket->Connect(resolved_address_, port_,
103 base::Bind(&SocketConnectFunction::OnCompleted, this)); 157 base::Bind(&SocketConnectFunction::OnConnect, this));
104 } 158 }
105 159
106 void SocketConnectFunction::OnCompleted(int result) { 160 void SocketConnectFunction::OnConnect(int result) {
107 result_.reset(Value::CreateIntegerValue(result)); 161 result_.reset(Value::CreateIntegerValue(result));
108 AsyncWorkCompleted(); 162 AsyncWorkCompleted();
163
164 // Added in StartDnsLookup().
165 Release();
109 } 166 }
110 167
111 bool SocketDisconnectFunction::Prepare() { 168 bool SocketDisconnectFunction::Prepare() {
112 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 169 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
113 return true; 170 return true;
114 } 171 }
115 172
116 void SocketDisconnectFunction::Work() { 173 void SocketDisconnectFunction::Work() {
117 Socket* socket = controller()->GetSocket(socket_id_); 174 Socket* socket = controller()->GetSocket(socket_id_);
118 if (socket) 175 if (socket)
(...skipping 15 matching lines...) Expand all
134 Socket* socket = controller()->GetSocket(socket_id_); 191 Socket* socket = controller()->GetSocket(socket_id_);
135 if (socket) 192 if (socket)
136 result = socket->Bind(address_, port_); 193 result = socket->Bind(address_, port_);
137 else 194 else
138 error_ = kSocketNotFoundError; 195 error_ = kSocketNotFoundError;
139 196
140 result_.reset(Value::CreateIntegerValue(result)); 197 result_.reset(Value::CreateIntegerValue(result));
141 } 198 }
142 199
143 SocketReadFunction::SocketReadFunction() 200 SocketReadFunction::SocketReadFunction()
144 : params_(NULL) { 201 : params_(NULL) {
145 } 202 }
146 203
147 SocketReadFunction::~SocketReadFunction() {} 204 SocketReadFunction::~SocketReadFunction() {}
148 205
149 bool SocketReadFunction::Prepare() { 206 bool SocketReadFunction::Prepare() {
150 params_ = api::experimental_socket::Read::Params::Create(*args_); 207 params_ = api::experimental_socket::Read::Params::Create(*args_);
151 EXTENSION_FUNCTION_VALIDATE(params_.get()); 208 EXTENSION_FUNCTION_VALIDATE(params_.get());
152 return true; 209 return true;
153 } 210 }
154 211
155 void SocketReadFunction::AsyncWorkStart() { 212 void SocketReadFunction::AsyncWorkStart() {
156 Socket* socket = controller()->GetSocket(params_->socket_id); 213 Socket* socket = controller()->GetSocket(params_->socket_id);
157 if (!socket) { 214 if (!socket) {
158 error_ = kSocketNotFoundError; 215 error_ = kSocketNotFoundError;
159 OnCompleted(-1, NULL); 216 OnCompleted(-1, NULL);
160 return; 217 return;
161 } 218 }
162 219
163 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096, 220 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096,
164 base::Bind(&SocketReadFunction::OnCompleted, this)); 221 base::Bind(&SocketReadFunction::OnCompleted, this));
165 } 222 }
166 223
167 void SocketReadFunction::OnCompleted(int bytes_read, 224 void SocketReadFunction::OnCompleted(int bytes_read,
168 scoped_refptr<net::IOBuffer> io_buffer) { 225 scoped_refptr<net::IOBuffer> io_buffer) {
169 DictionaryValue* result = new DictionaryValue(); 226 DictionaryValue* result = new DictionaryValue();
170 result->SetInteger(kResultCodeKey, bytes_read); 227 result->SetInteger(kResultCodeKey, bytes_read);
171 if (bytes_read > 0) { 228 if (bytes_read > 0) {
172 result->Set(kDataKey, 229 result->Set(kDataKey,
173 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), 230 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(),
174 bytes_read)); 231 bytes_read));
175 } else { 232 } else {
176 // BinaryValue does not support NULL buffer. Workaround it with new char[1]. 233 // BinaryValue does not support NULL buffer. Workaround it with new char[1].
177 // http://crbug.com/127630 234 // http://crbug.com/127630
178 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0)); 235 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0));
179 } 236 }
180 result_.reset(result); 237 result_.reset(result);
181 238
182 AsyncWorkCompleted(); 239 AsyncWorkCompleted();
183 } 240 }
184 241
(...skipping 18 matching lines...) Expand all
203 void SocketWriteFunction::AsyncWorkStart() { 260 void SocketWriteFunction::AsyncWorkStart() {
204 Socket* socket = controller()->GetSocket(socket_id_); 261 Socket* socket = controller()->GetSocket(socket_id_);
205 262
206 if (!socket) { 263 if (!socket) {
207 error_ = kSocketNotFoundError; 264 error_ = kSocketNotFoundError;
208 OnCompleted(-1); 265 OnCompleted(-1);
209 return; 266 return;
210 } 267 }
211 268
212 socket->Write(io_buffer_, io_buffer_size_, 269 socket->Write(io_buffer_, io_buffer_size_,
213 base::Bind(&SocketWriteFunction::OnCompleted, this)); 270 base::Bind(&SocketWriteFunction::OnCompleted, this));
214 } 271 }
215 272
216 void SocketWriteFunction::OnCompleted(int bytes_written) { 273 void SocketWriteFunction::OnCompleted(int bytes_written) {
217 DictionaryValue* result = new DictionaryValue(); 274 DictionaryValue* result = new DictionaryValue();
218 result->SetInteger(kBytesWrittenKey, bytes_written); 275 result->SetInteger(kBytesWrittenKey, bytes_written);
219 result_.reset(result); 276 result_.reset(result);
220 277
221 AsyncWorkCompleted(); 278 AsyncWorkCompleted();
222 } 279 }
223 280
224 SocketRecvFromFunction::SocketRecvFromFunction() 281 SocketRecvFromFunction::SocketRecvFromFunction()
225 : params_(NULL) { 282 : params_(NULL) {
226 } 283 }
227 284
228 SocketRecvFromFunction::~SocketRecvFromFunction() {} 285 SocketRecvFromFunction::~SocketRecvFromFunction() {}
229 286
230 bool SocketRecvFromFunction::Prepare() { 287 bool SocketRecvFromFunction::Prepare() {
231 params_ = api::experimental_socket::RecvFrom::Params::Create(*args_); 288 params_ = api::experimental_socket::RecvFrom::Params::Create(*args_);
232 EXTENSION_FUNCTION_VALIDATE(params_.get()); 289 EXTENSION_FUNCTION_VALIDATE(params_.get());
233 return true; 290 return true;
234 } 291 }
235 292
236 void SocketRecvFromFunction::AsyncWorkStart() { 293 void SocketRecvFromFunction::AsyncWorkStart() {
237 Socket* socket = controller()->GetSocket(params_->socket_id); 294 Socket* socket = controller()->GetSocket(params_->socket_id);
238 if (!socket) { 295 if (!socket) {
239 error_ = kSocketNotFoundError; 296 error_ = kSocketNotFoundError;
240 OnCompleted(-1, NULL, std::string(), 0); 297 OnCompleted(-1, NULL, std::string(), 0);
241 return; 298 return;
242 } 299 }
243 300
244 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096, 301 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096,
245 base::Bind(&SocketRecvFromFunction::OnCompleted, this)); 302 base::Bind(&SocketRecvFromFunction::OnCompleted, this));
246 } 303 }
247 304
248 void SocketRecvFromFunction::OnCompleted(int bytes_read, 305 void SocketRecvFromFunction::OnCompleted(int bytes_read,
249 scoped_refptr<net::IOBuffer> io_buffer, 306 scoped_refptr<net::IOBuffer> io_buffer,
250 const std::string& address, 307 const std::string& address,
251 int port) { 308 int port) {
252 DictionaryValue* result = new DictionaryValue(); 309 DictionaryValue* result = new DictionaryValue();
253 result->SetInteger(kResultCodeKey, bytes_read); 310 result->SetInteger(kResultCodeKey, bytes_read);
254 if (bytes_read > 0) { 311 if (bytes_read > 0) {
255 result->Set(kDataKey, 312 result->Set(kDataKey,
256 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), 313 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(),
257 bytes_read)); 314 bytes_read));
258 } else { 315 } else {
259 // BinaryValue does not support NULL buffer. Workaround it with new char[1]. 316 // BinaryValue does not support NULL buffer. Workaround it with new char[1].
260 // http://crbug.com/127630 317 // http://crbug.com/127630
261 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0)); 318 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0));
262 } 319 }
263 result->SetString(kAddressKey, address); 320 result->SetString(kAddressKey, address);
264 result->SetInteger(kPortKey, port); 321 result->SetInteger(kPortKey, port);
265 result_.reset(result); 322 result_.reset(result);
266 323
267 AsyncWorkCompleted(); 324 AsyncWorkCompleted();
(...skipping 21 matching lines...) Expand all
289 346
290 void SocketSendToFunction::AsyncWorkStart() { 347 void SocketSendToFunction::AsyncWorkStart() {
291 Socket* socket = controller()->GetSocket(socket_id_); 348 Socket* socket = controller()->GetSocket(socket_id_);
292 if (!socket) { 349 if (!socket) {
293 error_ = kSocketNotFoundError; 350 error_ = kSocketNotFoundError;
294 OnCompleted(-1); 351 OnCompleted(-1);
295 return; 352 return;
296 } 353 }
297 354
298 socket->SendTo(io_buffer_, io_buffer_size_, address_, port_, 355 socket->SendTo(io_buffer_, io_buffer_size_, address_, port_,
299 base::Bind(&SocketSendToFunction::OnCompleted, this)); 356 base::Bind(&SocketSendToFunction::OnCompleted, this));
300 } 357 }
301 358
302 void SocketSendToFunction::OnCompleted(int bytes_written) { 359 void SocketSendToFunction::OnCompleted(int bytes_written) {
303 DictionaryValue* result = new DictionaryValue(); 360 DictionaryValue* result = new DictionaryValue();
304 result->SetInteger(kBytesWrittenKey, bytes_written); 361 result->SetInteger(kBytesWrittenKey, bytes_written);
305 result_.reset(result); 362 result_.reset(result);
306 363
307 AsyncWorkCompleted(); 364 AsyncWorkCompleted();
308 } 365 }
309 366
310 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction() 367 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction()
311 : params_(NULL) { 368 : params_(NULL) {
312 } 369 }
313 370
314 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {} 371 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {}
315 372
316 bool SocketSetKeepAliveFunction::Prepare() { 373 bool SocketSetKeepAliveFunction::Prepare() {
317 params_ = api::experimental_socket::SetKeepAlive::Params::Create(*args_); 374 params_ = api::experimental_socket::SetKeepAlive::Params::Create(*args_);
318 EXTENSION_FUNCTION_VALIDATE(params_.get()); 375 EXTENSION_FUNCTION_VALIDATE(params_.get());
319 return true; 376 return true;
320 } 377 }
321 378
322 void SocketSetKeepAliveFunction::Work() { 379 void SocketSetKeepAliveFunction::Work() {
323 bool result = false; 380 bool result = false;
324 Socket* socket = controller()->GetSocket(params_->socket_id); 381 Socket* socket = controller()->GetSocket(params_->socket_id);
325 if (socket) { 382 if (socket) {
326 int delay = 0; 383 int delay = 0;
327 if (params_->delay.get()) 384 if (params_->delay.get())
328 delay = *params_->delay; 385 delay = *params_->delay;
329 result = socket->SetKeepAlive(params_->enable, delay); 386 result = socket->SetKeepAlive(params_->enable, delay);
330 } else { 387 } else {
331 error_ = kSocketNotFoundError; 388 error_ = kSocketNotFoundError;
332 } 389 }
333 result_.reset(Value::CreateBooleanValue(result)); 390 result_.reset(Value::CreateBooleanValue(result));
334 } 391 }
335 392
336 SocketSetNoDelayFunction::SocketSetNoDelayFunction() 393 SocketSetNoDelayFunction::SocketSetNoDelayFunction()
337 : params_(NULL) { 394 : params_(NULL) {
338 } 395 }
339 396
340 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {} 397 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {}
341 398
342 bool SocketSetNoDelayFunction::Prepare() { 399 bool SocketSetNoDelayFunction::Prepare() {
343 params_ = api::experimental_socket::SetNoDelay::Params::Create(*args_); 400 params_ = api::experimental_socket::SetNoDelay::Params::Create(*args_);
344 EXTENSION_FUNCTION_VALIDATE(params_.get()); 401 EXTENSION_FUNCTION_VALIDATE(params_.get());
345 return true; 402 return true;
346 } 403 }
347 404
348 void SocketSetNoDelayFunction::Work() { 405 void SocketSetNoDelayFunction::Work() {
349 bool result = false; 406 bool result = false;
350 Socket* socket = controller()->GetSocket(params_->socket_id); 407 Socket* socket = controller()->GetSocket(params_->socket_id);
351 if (socket) 408 if (socket)
352 result = socket->SetNoDelay(params_->no_delay); 409 result = socket->SetNoDelay(params_->no_delay);
353 else 410 else
354 error_ = kSocketNotFoundError; 411 error_ = kSocketNotFoundError;
355 result_.reset(Value::CreateBooleanValue(result)); 412 result_.reset(Value::CreateBooleanValue(result));
356 } 413 }
414
357 } // namespace extensions 415 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/socket/socket_api.h ('k') | chrome/browser/extensions/api/socket/socket_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698