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

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: Patch Set 1 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 OnDnsLookup.
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 AddRef(); // Balanced in OnConnect().
145 OnConnect(resolve_result);
146 }
147 Release(); // Added in StartDnsLookup().
Mihai Parparita -not on Chrome 2012/06/07 00:29:44 Do you need to the AddRef/Release in this method?
miket_OOO 2012/06/07 17:36:13 You're right. I simplified the code path in an ear
148 }
149
150 void SocketConnectFunction::StartConnect() {
95 Socket* socket = controller()->GetSocket(socket_id_); 151 Socket* socket = controller()->GetSocket(socket_id_);
96 if (!socket) { 152 if (!socket) {
97 error_ = kSocketNotFoundError; 153 error_ = kSocketNotFoundError;
98 OnCompleted(-1); 154 OnConnect(-1);
Mihai Parparita -not on Chrome 2012/06/07 00:29:44 If you do keep the current ref counting scheme, th
miket_OOO 2012/06/07 17:36:13 Doh. (Moot because I followed your earlier suggest
99 return; 155 return;
100 } 156 }
101 157
102 socket->Connect(address_, port_, 158 socket->Connect(resolved_address_, port_,
103 base::Bind(&SocketConnectFunction::OnCompleted, this)); 159 base::Bind(&SocketConnectFunction::OnConnect, this));
160
161 // Balanced in OnConnect().
162 AddRef();
104 } 163 }
105 164
106 void SocketConnectFunction::OnCompleted(int result) { 165 void SocketConnectFunction::OnConnect(int result) {
107 result_.reset(Value::CreateIntegerValue(result)); 166 result_.reset(Value::CreateIntegerValue(result));
108 AsyncWorkCompleted(); 167 AsyncWorkCompleted();
168 Release(); // Added in StartConnect() or OnDnsLookup()'s error case.
109 } 169 }
110 170
111 bool SocketDisconnectFunction::Prepare() { 171 bool SocketDisconnectFunction::Prepare() {
112 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); 172 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
113 return true; 173 return true;
114 } 174 }
115 175
116 void SocketDisconnectFunction::Work() { 176 void SocketDisconnectFunction::Work() {
117 Socket* socket = controller()->GetSocket(socket_id_); 177 Socket* socket = controller()->GetSocket(socket_id_);
118 if (socket) 178 if (socket)
(...skipping 15 matching lines...) Expand all
134 Socket* socket = controller()->GetSocket(socket_id_); 194 Socket* socket = controller()->GetSocket(socket_id_);
135 if (socket) 195 if (socket)
136 result = socket->Bind(address_, port_); 196 result = socket->Bind(address_, port_);
137 else 197 else
138 error_ = kSocketNotFoundError; 198 error_ = kSocketNotFoundError;
139 199
140 result_.reset(Value::CreateIntegerValue(result)); 200 result_.reset(Value::CreateIntegerValue(result));
141 } 201 }
142 202
143 SocketReadFunction::SocketReadFunction() 203 SocketReadFunction::SocketReadFunction()
144 : params_(NULL) { 204 : params_(NULL) {
145 } 205 }
146 206
147 SocketReadFunction::~SocketReadFunction() {} 207 SocketReadFunction::~SocketReadFunction() {}
148 208
149 bool SocketReadFunction::Prepare() { 209 bool SocketReadFunction::Prepare() {
150 params_ = api::experimental_socket::Read::Params::Create(*args_); 210 params_ = api::experimental_socket::Read::Params::Create(*args_);
151 EXTENSION_FUNCTION_VALIDATE(params_.get()); 211 EXTENSION_FUNCTION_VALIDATE(params_.get());
152 return true; 212 return true;
153 } 213 }
154 214
155 void SocketReadFunction::AsyncWorkStart() { 215 void SocketReadFunction::AsyncWorkStart() {
156 Socket* socket = controller()->GetSocket(params_->socket_id); 216 Socket* socket = controller()->GetSocket(params_->socket_id);
157 if (!socket) { 217 if (!socket) {
158 error_ = kSocketNotFoundError; 218 error_ = kSocketNotFoundError;
159 OnCompleted(-1, NULL); 219 OnCompleted(-1, NULL);
160 return; 220 return;
161 } 221 }
162 222
163 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096, 223 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096,
164 base::Bind(&SocketReadFunction::OnCompleted, this)); 224 base::Bind(&SocketReadFunction::OnCompleted, this));
165 } 225 }
166 226
167 void SocketReadFunction::OnCompleted(int bytes_read, 227 void SocketReadFunction::OnCompleted(int bytes_read,
168 scoped_refptr<net::IOBuffer> io_buffer) { 228 scoped_refptr<net::IOBuffer> io_buffer) {
169 DictionaryValue* result = new DictionaryValue(); 229 DictionaryValue* result = new DictionaryValue();
170 result->SetInteger(kResultCodeKey, bytes_read); 230 result->SetInteger(kResultCodeKey, bytes_read);
171 if (bytes_read > 0) { 231 if (bytes_read > 0) {
172 result->Set(kDataKey, 232 result->Set(kDataKey,
173 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), 233 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(),
174 bytes_read)); 234 bytes_read));
175 } else { 235 } else {
176 // BinaryValue does not support NULL buffer. Workaround it with new char[1]. 236 // BinaryValue does not support NULL buffer. Workaround it with new char[1].
177 // http://crbug.com/127630 237 // http://crbug.com/127630
178 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0)); 238 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0));
179 } 239 }
180 result_.reset(result); 240 result_.reset(result);
181 241
182 AsyncWorkCompleted(); 242 AsyncWorkCompleted();
183 } 243 }
184 244
(...skipping 18 matching lines...) Expand all
203 void SocketWriteFunction::AsyncWorkStart() { 263 void SocketWriteFunction::AsyncWorkStart() {
204 Socket* socket = controller()->GetSocket(socket_id_); 264 Socket* socket = controller()->GetSocket(socket_id_);
205 265
206 if (!socket) { 266 if (!socket) {
207 error_ = kSocketNotFoundError; 267 error_ = kSocketNotFoundError;
208 OnCompleted(-1); 268 OnCompleted(-1);
209 return; 269 return;
210 } 270 }
211 271
212 socket->Write(io_buffer_, io_buffer_size_, 272 socket->Write(io_buffer_, io_buffer_size_,
213 base::Bind(&SocketWriteFunction::OnCompleted, this)); 273 base::Bind(&SocketWriteFunction::OnCompleted, this));
214 } 274 }
215 275
216 void SocketWriteFunction::OnCompleted(int bytes_written) { 276 void SocketWriteFunction::OnCompleted(int bytes_written) {
217 DictionaryValue* result = new DictionaryValue(); 277 DictionaryValue* result = new DictionaryValue();
218 result->SetInteger(kBytesWrittenKey, bytes_written); 278 result->SetInteger(kBytesWrittenKey, bytes_written);
219 result_.reset(result); 279 result_.reset(result);
220 280
221 AsyncWorkCompleted(); 281 AsyncWorkCompleted();
222 } 282 }
223 283
224 SocketRecvFromFunction::SocketRecvFromFunction() 284 SocketRecvFromFunction::SocketRecvFromFunction()
225 : params_(NULL) { 285 : params_(NULL) {
226 } 286 }
227 287
228 SocketRecvFromFunction::~SocketRecvFromFunction() {} 288 SocketRecvFromFunction::~SocketRecvFromFunction() {}
229 289
230 bool SocketRecvFromFunction::Prepare() { 290 bool SocketRecvFromFunction::Prepare() {
231 params_ = api::experimental_socket::RecvFrom::Params::Create(*args_); 291 params_ = api::experimental_socket::RecvFrom::Params::Create(*args_);
232 EXTENSION_FUNCTION_VALIDATE(params_.get()); 292 EXTENSION_FUNCTION_VALIDATE(params_.get());
233 return true; 293 return true;
234 } 294 }
235 295
236 void SocketRecvFromFunction::AsyncWorkStart() { 296 void SocketRecvFromFunction::AsyncWorkStart() {
237 Socket* socket = controller()->GetSocket(params_->socket_id); 297 Socket* socket = controller()->GetSocket(params_->socket_id);
238 if (!socket) { 298 if (!socket) {
239 error_ = kSocketNotFoundError; 299 error_ = kSocketNotFoundError;
240 OnCompleted(-1, NULL, std::string(), 0); 300 OnCompleted(-1, NULL, std::string(), 0);
241 return; 301 return;
242 } 302 }
243 303
244 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096, 304 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096,
245 base::Bind(&SocketRecvFromFunction::OnCompleted, this)); 305 base::Bind(&SocketRecvFromFunction::OnCompleted, this));
246 } 306 }
247 307
248 void SocketRecvFromFunction::OnCompleted(int bytes_read, 308 void SocketRecvFromFunction::OnCompleted(int bytes_read,
249 scoped_refptr<net::IOBuffer> io_buffer, 309 scoped_refptr<net::IOBuffer> io_buffer,
250 const std::string& address, 310 const std::string& address,
251 int port) { 311 int port) {
252 DictionaryValue* result = new DictionaryValue(); 312 DictionaryValue* result = new DictionaryValue();
253 result->SetInteger(kResultCodeKey, bytes_read); 313 result->SetInteger(kResultCodeKey, bytes_read);
254 if (bytes_read > 0) { 314 if (bytes_read > 0) {
255 result->Set(kDataKey, 315 result->Set(kDataKey,
256 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), 316 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(),
257 bytes_read)); 317 bytes_read));
258 } else { 318 } else {
259 // BinaryValue does not support NULL buffer. Workaround it with new char[1]. 319 // BinaryValue does not support NULL buffer. Workaround it with new char[1].
260 // http://crbug.com/127630 320 // http://crbug.com/127630
261 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0)); 321 result->Set(kDataKey, base::BinaryValue::Create(new char[1], 0));
262 } 322 }
263 result->SetString(kAddressKey, address); 323 result->SetString(kAddressKey, address);
264 result->SetInteger(kPortKey, port); 324 result->SetInteger(kPortKey, port);
265 result_.reset(result); 325 result_.reset(result);
266 326
267 AsyncWorkCompleted(); 327 AsyncWorkCompleted();
(...skipping 21 matching lines...) Expand all
289 349
290 void SocketSendToFunction::AsyncWorkStart() { 350 void SocketSendToFunction::AsyncWorkStart() {
291 Socket* socket = controller()->GetSocket(socket_id_); 351 Socket* socket = controller()->GetSocket(socket_id_);
292 if (!socket) { 352 if (!socket) {
293 error_ = kSocketNotFoundError; 353 error_ = kSocketNotFoundError;
294 OnCompleted(-1); 354 OnCompleted(-1);
295 return; 355 return;
296 } 356 }
297 357
298 socket->SendTo(io_buffer_, io_buffer_size_, address_, port_, 358 socket->SendTo(io_buffer_, io_buffer_size_, address_, port_,
299 base::Bind(&SocketSendToFunction::OnCompleted, this)); 359 base::Bind(&SocketSendToFunction::OnCompleted, this));
300 } 360 }
301 361
302 void SocketSendToFunction::OnCompleted(int bytes_written) { 362 void SocketSendToFunction::OnCompleted(int bytes_written) {
303 DictionaryValue* result = new DictionaryValue(); 363 DictionaryValue* result = new DictionaryValue();
304 result->SetInteger(kBytesWrittenKey, bytes_written); 364 result->SetInteger(kBytesWrittenKey, bytes_written);
305 result_.reset(result); 365 result_.reset(result);
306 366
307 AsyncWorkCompleted(); 367 AsyncWorkCompleted();
308 } 368 }
309 369
310 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction() 370 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction()
311 : params_(NULL) { 371 : params_(NULL) {
312 } 372 }
313 373
314 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {} 374 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {}
315 375
316 bool SocketSetKeepAliveFunction::Prepare() { 376 bool SocketSetKeepAliveFunction::Prepare() {
317 params_ = api::experimental_socket::SetKeepAlive::Params::Create(*args_); 377 params_ = api::experimental_socket::SetKeepAlive::Params::Create(*args_);
318 EXTENSION_FUNCTION_VALIDATE(params_.get()); 378 EXTENSION_FUNCTION_VALIDATE(params_.get());
319 return true; 379 return true;
320 } 380 }
321 381
322 void SocketSetKeepAliveFunction::Work() { 382 void SocketSetKeepAliveFunction::Work() {
323 bool result = false; 383 bool result = false;
324 Socket* socket = controller()->GetSocket(params_->socket_id); 384 Socket* socket = controller()->GetSocket(params_->socket_id);
325 if (socket) { 385 if (socket) {
326 int delay = 0; 386 int delay = 0;
327 if (params_->delay.get()) 387 if (params_->delay.get())
328 delay = *params_->delay; 388 delay = *params_->delay;
329 result = socket->SetKeepAlive(params_->enable, delay); 389 result = socket->SetKeepAlive(params_->enable, delay);
330 } else { 390 } else {
331 error_ = kSocketNotFoundError; 391 error_ = kSocketNotFoundError;
332 } 392 }
333 result_.reset(Value::CreateBooleanValue(result)); 393 result_.reset(Value::CreateBooleanValue(result));
334 } 394 }
335 395
336 SocketSetNoDelayFunction::SocketSetNoDelayFunction() 396 SocketSetNoDelayFunction::SocketSetNoDelayFunction()
337 : params_(NULL) { 397 : params_(NULL) {
338 } 398 }
339 399
340 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {} 400 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {}
341 401
342 bool SocketSetNoDelayFunction::Prepare() { 402 bool SocketSetNoDelayFunction::Prepare() {
343 params_ = api::experimental_socket::SetNoDelay::Params::Create(*args_); 403 params_ = api::experimental_socket::SetNoDelay::Params::Create(*args_);
344 EXTENSION_FUNCTION_VALIDATE(params_.get()); 404 EXTENSION_FUNCTION_VALIDATE(params_.get());
345 return true; 405 return true;
346 } 406 }
347 407
348 void SocketSetNoDelayFunction::Work() { 408 void SocketSetNoDelayFunction::Work() {
349 bool result = false; 409 bool result = false;
350 Socket* socket = controller()->GetSocket(params_->socket_id); 410 Socket* socket = controller()->GetSocket(params_->socket_id);
351 if (socket) 411 if (socket)
352 result = socket->SetNoDelay(params_->no_delay); 412 result = socket->SetNoDelay(params_->no_delay);
353 else 413 else
354 error_ = kSocketNotFoundError; 414 error_ = kSocketNotFoundError;
355 result_.reset(Value::CreateBooleanValue(result)); 415 result_.reset(Value::CreateBooleanValue(result));
356 } 416 }
417
357 } // namespace extensions 418 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698