Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/common/extensions/permissions/socket_permission.h" | |
| 8 #include "chrome/browser/browser_process.h" | 9 #include "chrome/browser/browser_process.h" |
| 9 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h" | 10 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h" |
| 10 #include "chrome/browser/extensions/api/socket/socket.h" | 11 #include "chrome/browser/extensions/api/socket/socket.h" |
| 11 #include "chrome/browser/extensions/api/socket/tcp_socket.h" | 12 #include "chrome/browser/extensions/api/socket/tcp_socket.h" |
| 12 #include "chrome/browser/extensions/api/socket/udp_socket.h" | 13 #include "chrome/browser/extensions/api/socket/udp_socket.h" |
| 13 #include "chrome/browser/extensions/extension_system.h" | 14 #include "chrome/browser/extensions/extension_system.h" |
| 14 #include "chrome/browser/io_thread.h" | 15 #include "chrome/browser/io_thread.h" |
| 15 #include "net/base/host_port_pair.h" | 16 #include "net/base/host_port_pair.h" |
| 16 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| 17 #include "net/base/ip_endpoint.h" | 18 #include "net/base/ip_endpoint.h" |
| 18 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 19 #include "net/base/net_log.h" | 20 #include "net/base/net_log.h" |
| 20 | 21 |
| 21 namespace extensions { | 22 namespace extensions { |
| 22 | 23 |
| 23 const char kAddressKey[] = "address"; | 24 const char kAddressKey[] = "address"; |
| 24 const char kPortKey[] = "port"; | 25 const char kPortKey[] = "port"; |
| 25 const char kBytesWrittenKey[] = "bytesWritten"; | 26 const char kBytesWrittenKey[] = "bytesWritten"; |
| 26 const char kDataKey[] = "data"; | 27 const char kDataKey[] = "data"; |
| 27 const char kResultCodeKey[] = "resultCode"; | 28 const char kResultCodeKey[] = "resultCode"; |
| 28 const char kSocketIdKey[] = "socketId"; | 29 const char kSocketIdKey[] = "socketId"; |
| 29 const char kTCPOption[] = "tcp"; | 30 const char kTCPOption[] = "tcp"; |
| 30 const char kUDPOption[] = "udp"; | 31 const char kUDPOption[] = "udp"; |
| 31 | 32 |
| 32 const char kSocketNotFoundError[] = "Socket not found"; | 33 const char kSocketNotFoundError[] = "Socket not found"; |
| 33 const char kSocketTypeInvalidError[] = "Socket type is not supported"; | 34 const char kSocketTypeInvalidError[] = "Socket type is not supported"; |
| 34 const char kDnsLookupFailedError[] = "DNS resolution failed"; | 35 const char kDnsLookupFailedError[] = "DNS resolution failed"; |
| 36 const char kNoPermission[] = "Caller does not have permission"; | |
|
miket_OOO
2012/08/06 21:04:06
Can you pick a constant name that's consistent wit
Peng
2012/08/07 21:31:55
Done. I replaced it with kPermissionError. If you
| |
| 35 | 37 |
| 36 SocketAsyncApiFunction::SocketAsyncApiFunction() | 38 SocketAsyncApiFunction::SocketAsyncApiFunction() |
| 37 : manager_(NULL) { | 39 : manager_(NULL) { |
| 38 } | 40 } |
| 39 | 41 |
| 40 SocketAsyncApiFunction::~SocketAsyncApiFunction() { | 42 SocketAsyncApiFunction::~SocketAsyncApiFunction() { |
| 41 } | 43 } |
| 42 | 44 |
| 43 bool SocketAsyncApiFunction::PrePrepare() { | 45 bool SocketAsyncApiFunction::PrePrepare() { |
| 44 manager_ = ExtensionSystem::Get(profile())->socket_manager(); | 46 manager_ = ExtensionSystem::Get(profile())->socket_manager(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 } | 158 } |
| 157 | 159 |
| 158 bool SocketConnectFunction::Prepare() { | 160 bool SocketConnectFunction::Prepare() { |
| 159 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); | 161 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
| 160 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_)); | 162 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_)); |
| 161 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); | 163 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); |
| 162 return true; | 164 return true; |
| 163 } | 165 } |
| 164 | 166 |
| 165 void SocketConnectFunction::AsyncWorkStart() { | 167 void SocketConnectFunction::AsyncWorkStart() { |
| 168 socket_ = manager_->Get(socket_id_); | |
| 169 if (!socket_) { | |
| 170 error_ = kSocketNotFoundError; | |
| 171 SetResult(Value::CreateIntegerValue(-1)); | |
| 172 AsyncWorkCompleted(); | |
| 173 return; | |
| 174 } | |
| 175 | |
| 176 SocketPermissionData::OperationType type; | |
| 177 switch (socket_->socket_type()) { | |
| 178 case Socket::TYPE_TCP: | |
| 179 type = SocketPermissionData::TCP_CONNECT; | |
| 180 break; | |
| 181 case Socket::TYPE_UDP: | |
| 182 type = SocketPermissionData::UDP_SEND_TO; | |
| 183 break; | |
| 184 default: | |
| 185 type = SocketPermissionData::NONE; | |
| 186 break; | |
| 187 } | |
| 188 | |
| 189 SocketPermission::CheckParam param(type, hostname_, port_); | |
| 190 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket, | |
| 191 ¶m)) { | |
| 192 error_ = kNoPermission; | |
| 193 SetResult(Value::CreateIntegerValue(-1)); | |
| 194 AsyncWorkCompleted(); | |
| 195 return; | |
| 196 } | |
| 197 | |
| 166 StartDnsLookup(hostname_); | 198 StartDnsLookup(hostname_); |
| 167 } | 199 } |
| 168 | 200 |
| 169 void SocketConnectFunction::AfterDnsLookup(int lookup_result) { | 201 void SocketConnectFunction::AfterDnsLookup(int lookup_result) { |
| 170 if (lookup_result == net::OK) { | 202 if (lookup_result == net::OK) { |
| 171 StartConnect(); | 203 StartConnect(); |
| 172 } else { | 204 } else { |
| 173 SetResult(Value::CreateIntegerValue(lookup_result)); | 205 SetResult(Value::CreateIntegerValue(lookup_result)); |
| 174 AsyncWorkCompleted(); | 206 AsyncWorkCompleted(); |
| 175 } | 207 } |
| 176 } | 208 } |
| 177 | 209 |
| 178 void SocketConnectFunction::StartConnect() { | 210 void SocketConnectFunction::StartConnect() { |
| 179 Socket* socket = manager_->Get(socket_id_); | 211 socket_->Connect(resolved_address_, port_, |
| 180 if (!socket) { | 212 base::Bind(&SocketConnectFunction::OnConnect, this)); |
| 181 error_ = kSocketNotFoundError; | |
| 182 OnConnect(-1); | |
| 183 return; | |
| 184 } | |
| 185 | |
| 186 socket->Connect(resolved_address_, port_, | |
| 187 base::Bind(&SocketConnectFunction::OnConnect, this)); | |
| 188 } | 213 } |
| 189 | 214 |
| 190 void SocketConnectFunction::OnConnect(int result) { | 215 void SocketConnectFunction::OnConnect(int result) { |
| 191 SetResult(Value::CreateIntegerValue(result)); | 216 SetResult(Value::CreateIntegerValue(result)); |
| 192 AsyncWorkCompleted(); | 217 AsyncWorkCompleted(); |
| 193 } | 218 } |
| 194 | 219 |
| 195 bool SocketDisconnectFunction::Prepare() { | 220 bool SocketDisconnectFunction::Prepare() { |
| 196 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); | 221 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
| 197 return true; | 222 return true; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 209 bool SocketBindFunction::Prepare() { | 234 bool SocketBindFunction::Prepare() { |
| 210 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); | 235 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_)); |
| 211 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); | 236 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_)); |
| 212 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); | 237 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_)); |
| 213 return true; | 238 return true; |
| 214 } | 239 } |
| 215 | 240 |
| 216 void SocketBindFunction::Work() { | 241 void SocketBindFunction::Work() { |
| 217 int result = -1; | 242 int result = -1; |
| 218 Socket* socket = manager_->Get(socket_id_); | 243 Socket* socket = manager_->Get(socket_id_); |
| 219 if (socket) | 244 SocketPermission::CheckParam param( |
| 220 result = socket->Bind(address_, port_); | 245 SocketPermissionData::UDP_BIND, address_, port_); |
| 221 else | 246 if (socket) { |
| 247 if (GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket, | |
| 248 ¶m)) | |
| 249 result = socket->Bind(address_, port_); | |
| 250 else | |
| 251 error_ = kNoPermission; | |
| 252 } else { | |
| 222 error_ = kSocketNotFoundError; | 253 error_ = kSocketNotFoundError; |
| 254 } | |
| 223 | 255 |
| 224 SetResult(Value::CreateIntegerValue(result)); | 256 SetResult(Value::CreateIntegerValue(result)); |
| 225 } | 257 } |
| 226 | 258 |
| 227 SocketReadFunction::SocketReadFunction() | 259 SocketReadFunction::SocketReadFunction() |
| 228 : params_(NULL) { | 260 : params_(NULL) { |
| 229 } | 261 } |
| 230 | 262 |
| 231 SocketReadFunction::~SocketReadFunction() {} | 263 SocketReadFunction::~SocketReadFunction() {} |
| 232 | 264 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); | 398 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); |
| 367 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_)); | 399 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_)); |
| 368 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_)); | 400 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_)); |
| 369 | 401 |
| 370 io_buffer_size_ = data->GetSize(); | 402 io_buffer_size_ = data->GetSize(); |
| 371 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); | 403 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); |
| 372 return true; | 404 return true; |
| 373 } | 405 } |
| 374 | 406 |
| 375 void SocketSendToFunction::AsyncWorkStart() { | 407 void SocketSendToFunction::AsyncWorkStart() { |
| 376 StartDnsLookup(hostname_); | 408 do { |
| 409 socket_ = manager_->Get(socket_id_); | |
| 410 if (!socket_) { | |
| 411 error_ = kSocketNotFoundError; | |
| 412 break; | |
| 413 } | |
| 414 | |
| 415 SocketPermission::CheckParam param(SocketPermissionData::UDP_SEND_TO, | |
| 416 hostname_, port_); | |
| 417 if (!GetExtension()->CheckAPIPermissionWithDetail(APIPermission::kSocket, | |
| 418 ¶m)) { | |
| 419 error_ = kNoPermission; | |
| 420 break; | |
| 421 } | |
| 422 | |
| 423 StartDnsLookup(hostname_); | |
| 424 return; | |
| 425 } while (false); | |
| 426 SetResult(Value::CreateIntegerValue(-1)); | |
| 427 AsyncWorkCompleted(); | |
| 377 } | 428 } |
| 378 | 429 |
| 379 void SocketSendToFunction::AfterDnsLookup(int lookup_result) { | 430 void SocketSendToFunction::AfterDnsLookup(int lookup_result) { |
| 380 if (lookup_result == net::OK) { | 431 if (lookup_result == net::OK) { |
| 381 StartSendTo(); | 432 StartSendTo(); |
| 382 } else { | 433 } else { |
| 383 SetResult(Value::CreateIntegerValue(lookup_result)); | 434 SetResult(Value::CreateIntegerValue(lookup_result)); |
| 384 AsyncWorkCompleted(); | 435 AsyncWorkCompleted(); |
| 385 } | 436 } |
| 386 } | 437 } |
| 387 | 438 |
| 388 void SocketSendToFunction::StartSendTo() { | 439 void SocketSendToFunction::StartSendTo() { |
| 389 Socket* socket = manager_->Get(socket_id_); | 440 socket_->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_, |
| 390 if (!socket) { | 441 base::Bind(&SocketSendToFunction::OnCompleted, this)); |
| 391 error_ = kSocketNotFoundError; | |
| 392 OnCompleted(-1); | |
| 393 return; | |
| 394 } | |
| 395 | |
| 396 socket->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_, | |
| 397 base::Bind(&SocketSendToFunction::OnCompleted, this)); | |
| 398 } | 442 } |
| 399 | 443 |
| 400 void SocketSendToFunction::OnCompleted(int bytes_written) { | 444 void SocketSendToFunction::OnCompleted(int bytes_written) { |
| 401 DictionaryValue* result = new DictionaryValue(); | 445 DictionaryValue* result = new DictionaryValue(); |
| 402 result->SetInteger(kBytesWrittenKey, bytes_written); | 446 result->SetInteger(kBytesWrittenKey, bytes_written); |
| 403 SetResult(result); | 447 SetResult(result); |
| 404 | 448 |
| 405 AsyncWorkCompleted(); | 449 AsyncWorkCompleted(); |
| 406 } | 450 } |
| 407 | 451 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 bool result = false; | 491 bool result = false; |
| 448 Socket* socket = manager_->Get(params_->socket_id); | 492 Socket* socket = manager_->Get(params_->socket_id); |
| 449 if (socket) | 493 if (socket) |
| 450 result = socket->SetNoDelay(params_->no_delay); | 494 result = socket->SetNoDelay(params_->no_delay); |
| 451 else | 495 else |
| 452 error_ = kSocketNotFoundError; | 496 error_ = kSocketNotFoundError; |
| 453 SetResult(Value::CreateBooleanValue(result)); | 497 SetResult(Value::CreateBooleanValue(result)); |
| 454 } | 498 } |
| 455 | 499 |
| 456 } // namespace extensions | 500 } // namespace extensions |
| OLD | NEW |