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. 4 5 #ifndef EXTENSIONS_BROWSER_API_SOCKET_SOCKET_API_H_ 6 #define EXTENSIONS_BROWSER_API_SOCKET_SOCKET_API_H_ 7 8 #include <string> 9 10 #include "base/gtest_prod_util.h" 11 #include "base/memory/ref_counted.h" 12 #include "extensions/browser/api/api_resource_manager.h" 13 #include "extensions/browser/api/async_api_function.h" 14 #include "extensions/browser/extension_function.h" 15 #include "extensions/common/api/socket.h" 16 #include "net/base/address_list.h" 17 #include "net/dns/host_resolver.h" 18 #include "net/socket/tcp_client_socket.h" 19 20 namespace content { 21 class BrowserContext; 22 class ResourceContext; 23 } 24 25 namespace net { 26 class IOBuffer; 27 } 28 29 namespace extensions { 30 31 class Socket; 32 33 // A simple interface to ApiResourceManager<Socket> or derived class. The goal 34 // of this interface is to allow Socket API functions to use distinct instances 35 // of ApiResourceManager<> depending on the type of socket (old version in 36 // "socket" namespace vs new version in "socket.xxx" namespaces). 37 class SocketResourceManagerInterface { 38 public: ~SocketResourceManagerInterface()39 virtual ~SocketResourceManagerInterface() {} 40 41 virtual bool SetBrowserContext(content::BrowserContext* context) = 0; 42 virtual int Add(Socket* socket) = 0; 43 virtual Socket* Get(const std::string& extension_id, int api_resource_id) = 0; 44 virtual void Remove(const std::string& extension_id, int api_resource_id) = 0; 45 virtual base::hash_set<int>* GetResourceIds( 46 const std::string& extension_id) = 0; 47 }; 48 49 // Implementation of SocketResourceManagerInterface using an 50 // ApiResourceManager<T> instance (where T derives from Socket). 51 template <typename T> 52 class SocketResourceManager : public SocketResourceManagerInterface { 53 public: SocketResourceManager()54 SocketResourceManager() : manager_(NULL) {} 55 SetBrowserContext(content::BrowserContext * context)56 virtual bool SetBrowserContext(content::BrowserContext* context) OVERRIDE { 57 manager_ = ApiResourceManager<T>::Get(context); 58 DCHECK(manager_) 59 << "There is no socket manager. " 60 "If this assertion is failing during a test, then it is likely that " 61 "TestExtensionSystem is failing to provide an instance of " 62 "ApiResourceManager<Socket>."; 63 return manager_ != NULL; 64 } 65 Add(Socket * socket)66 virtual int Add(Socket* socket) OVERRIDE { 67 // Note: Cast needed here, because "T" may be a subclass of "Socket". 68 return manager_->Add(static_cast<T*>(socket)); 69 } 70 Get(const std::string & extension_id,int api_resource_id)71 virtual Socket* Get(const std::string& extension_id, 72 int api_resource_id) OVERRIDE { 73 return manager_->Get(extension_id, api_resource_id); 74 } 75 Remove(const std::string & extension_id,int api_resource_id)76 virtual void Remove(const std::string& extension_id, 77 int api_resource_id) OVERRIDE { 78 manager_->Remove(extension_id, api_resource_id); 79 } 80 GetResourceIds(const std::string & extension_id)81 virtual base::hash_set<int>* GetResourceIds(const std::string& extension_id) 82 OVERRIDE { 83 return manager_->GetResourceIds(extension_id); 84 } 85 86 private: 87 ApiResourceManager<T>* manager_; 88 }; 89 90 class SocketAsyncApiFunction : public AsyncApiFunction { 91 public: 92 SocketAsyncApiFunction(); 93 94 protected: 95 virtual ~SocketAsyncApiFunction(); 96 97 // AsyncApiFunction: 98 virtual bool PrePrepare() OVERRIDE; 99 virtual bool Respond() OVERRIDE; 100 101 virtual scoped_ptr<SocketResourceManagerInterface> 102 CreateSocketResourceManager(); 103 104 int AddSocket(Socket* socket); 105 Socket* GetSocket(int api_resource_id); 106 void RemoveSocket(int api_resource_id); 107 base::hash_set<int>* GetSocketIds(); 108 109 private: 110 scoped_ptr<SocketResourceManagerInterface> manager_; 111 }; 112 113 class SocketExtensionWithDnsLookupFunction : public SocketAsyncApiFunction { 114 protected: 115 SocketExtensionWithDnsLookupFunction(); 116 virtual ~SocketExtensionWithDnsLookupFunction(); 117 118 // AsyncApiFunction: 119 virtual bool PrePrepare() OVERRIDE; 120 121 void StartDnsLookup(const std::string& hostname); 122 virtual void AfterDnsLookup(int lookup_result) = 0; 123 124 std::string resolved_address_; 125 126 private: 127 void OnDnsLookup(int resolve_result); 128 129 // Weak pointer to the resource context. 130 content::ResourceContext* resource_context_; 131 132 scoped_ptr<net::HostResolver::RequestHandle> request_handle_; 133 scoped_ptr<net::AddressList> addresses_; 134 }; 135 136 class SocketCreateFunction : public SocketAsyncApiFunction { 137 public: 138 DECLARE_EXTENSION_FUNCTION("socket.create", SOCKET_CREATE) 139 140 SocketCreateFunction(); 141 142 protected: 143 virtual ~SocketCreateFunction(); 144 145 // AsyncApiFunction: 146 virtual bool Prepare() OVERRIDE; 147 virtual void Work() OVERRIDE; 148 149 private: 150 FRIEND_TEST_ALL_PREFIXES(SocketUnitTest, Create); 151 enum SocketType { kSocketTypeInvalid = -1, kSocketTypeTCP, kSocketTypeUDP }; 152 153 scoped_ptr<core_api::socket::Create::Params> params_; 154 SocketType socket_type_; 155 }; 156 157 class SocketDestroyFunction : public SocketAsyncApiFunction { 158 public: 159 DECLARE_EXTENSION_FUNCTION("socket.destroy", SOCKET_DESTROY) 160 161 protected: ~SocketDestroyFunction()162 virtual ~SocketDestroyFunction() {} 163 164 // AsyncApiFunction: 165 virtual bool Prepare() OVERRIDE; 166 virtual void Work() OVERRIDE; 167 168 private: 169 int socket_id_; 170 }; 171 172 class SocketConnectFunction : public SocketExtensionWithDnsLookupFunction { 173 public: 174 DECLARE_EXTENSION_FUNCTION("socket.connect", SOCKET_CONNECT) 175 176 SocketConnectFunction(); 177 178 protected: 179 virtual ~SocketConnectFunction(); 180 181 // AsyncApiFunction: 182 virtual bool Prepare() OVERRIDE; 183 virtual void AsyncWorkStart() OVERRIDE; 184 185 // SocketExtensionWithDnsLookupFunction: 186 virtual void AfterDnsLookup(int lookup_result) OVERRIDE; 187 188 private: 189 void StartConnect(); 190 void OnConnect(int result); 191 192 int socket_id_; 193 std::string hostname_; 194 int port_; 195 Socket* socket_; 196 }; 197 198 class SocketDisconnectFunction : public SocketAsyncApiFunction { 199 public: 200 DECLARE_EXTENSION_FUNCTION("socket.disconnect", SOCKET_DISCONNECT) 201 202 protected: ~SocketDisconnectFunction()203 virtual ~SocketDisconnectFunction() {} 204 205 // AsyncApiFunction: 206 virtual bool Prepare() OVERRIDE; 207 virtual void Work() OVERRIDE; 208 209 private: 210 int socket_id_; 211 }; 212 213 class SocketBindFunction : public SocketAsyncApiFunction { 214 public: 215 DECLARE_EXTENSION_FUNCTION("socket.bind", SOCKET_BIND) 216 217 protected: ~SocketBindFunction()218 virtual ~SocketBindFunction() {} 219 220 // AsyncApiFunction: 221 virtual bool Prepare() OVERRIDE; 222 virtual void Work() OVERRIDE; 223 224 private: 225 int socket_id_; 226 std::string address_; 227 int port_; 228 }; 229 230 class SocketListenFunction : public SocketAsyncApiFunction { 231 public: 232 DECLARE_EXTENSION_FUNCTION("socket.listen", SOCKET_LISTEN) 233 234 SocketListenFunction(); 235 236 protected: 237 virtual ~SocketListenFunction(); 238 239 // AsyncApiFunction: 240 virtual bool Prepare() OVERRIDE; 241 virtual void Work() OVERRIDE; 242 243 private: 244 scoped_ptr<core_api::socket::Listen::Params> params_; 245 }; 246 247 class SocketAcceptFunction : public SocketAsyncApiFunction { 248 public: 249 DECLARE_EXTENSION_FUNCTION("socket.accept", SOCKET_ACCEPT) 250 251 SocketAcceptFunction(); 252 253 protected: 254 virtual ~SocketAcceptFunction(); 255 256 // AsyncApiFunction: 257 virtual bool Prepare() OVERRIDE; 258 virtual void AsyncWorkStart() OVERRIDE; 259 260 private: 261 void OnAccept(int result_code, net::TCPClientSocket* socket); 262 263 scoped_ptr<core_api::socket::Accept::Params> params_; 264 }; 265 266 class SocketReadFunction : public SocketAsyncApiFunction { 267 public: 268 DECLARE_EXTENSION_FUNCTION("socket.read", SOCKET_READ) 269 270 SocketReadFunction(); 271 272 protected: 273 virtual ~SocketReadFunction(); 274 275 // AsyncApiFunction: 276 virtual bool Prepare() OVERRIDE; 277 virtual void AsyncWorkStart() OVERRIDE; 278 void OnCompleted(int result, scoped_refptr<net::IOBuffer> io_buffer); 279 280 private: 281 scoped_ptr<core_api::socket::Read::Params> params_; 282 }; 283 284 class SocketWriteFunction : public SocketAsyncApiFunction { 285 public: 286 DECLARE_EXTENSION_FUNCTION("socket.write", SOCKET_WRITE) 287 288 SocketWriteFunction(); 289 290 protected: 291 virtual ~SocketWriteFunction(); 292 293 // AsyncApiFunction: 294 virtual bool Prepare() OVERRIDE; 295 virtual void AsyncWorkStart() OVERRIDE; 296 void OnCompleted(int result); 297 298 private: 299 int socket_id_; 300 scoped_refptr<net::IOBuffer> io_buffer_; 301 size_t io_buffer_size_; 302 }; 303 304 class SocketRecvFromFunction : public SocketAsyncApiFunction { 305 public: 306 DECLARE_EXTENSION_FUNCTION("socket.recvFrom", SOCKET_RECVFROM) 307 308 SocketRecvFromFunction(); 309 310 protected: 311 virtual ~SocketRecvFromFunction(); 312 313 // AsyncApiFunction 314 virtual bool Prepare() OVERRIDE; 315 virtual void AsyncWorkStart() OVERRIDE; 316 void OnCompleted(int result, 317 scoped_refptr<net::IOBuffer> io_buffer, 318 const std::string& address, 319 int port); 320 321 private: 322 scoped_ptr<core_api::socket::RecvFrom::Params> params_; 323 }; 324 325 class SocketSendToFunction : public SocketExtensionWithDnsLookupFunction { 326 public: 327 DECLARE_EXTENSION_FUNCTION("socket.sendTo", SOCKET_SENDTO) 328 329 SocketSendToFunction(); 330 331 protected: 332 virtual ~SocketSendToFunction(); 333 334 // AsyncApiFunction: 335 virtual bool Prepare() OVERRIDE; 336 virtual void AsyncWorkStart() OVERRIDE; 337 void OnCompleted(int result); 338 339 // SocketExtensionWithDnsLookupFunction: 340 virtual void AfterDnsLookup(int lookup_result) OVERRIDE; 341 342 private: 343 void StartSendTo(); 344 345 int socket_id_; 346 scoped_refptr<net::IOBuffer> io_buffer_; 347 size_t io_buffer_size_; 348 std::string hostname_; 349 int port_; 350 Socket* socket_; 351 }; 352 353 class SocketSetKeepAliveFunction : public SocketAsyncApiFunction { 354 public: 355 DECLARE_EXTENSION_FUNCTION("socket.setKeepAlive", SOCKET_SETKEEPALIVE) 356 357 SocketSetKeepAliveFunction(); 358 359 protected: 360 virtual ~SocketSetKeepAliveFunction(); 361 362 // AsyncApiFunction: 363 virtual bool Prepare() OVERRIDE; 364 virtual void Work() OVERRIDE; 365 366 private: 367 scoped_ptr<core_api::socket::SetKeepAlive::Params> params_; 368 }; 369 370 class SocketSetNoDelayFunction : public SocketAsyncApiFunction { 371 public: 372 DECLARE_EXTENSION_FUNCTION("socket.setNoDelay", SOCKET_SETNODELAY) 373 374 SocketSetNoDelayFunction(); 375 376 protected: 377 virtual ~SocketSetNoDelayFunction(); 378 379 // AsyncApiFunction: 380 virtual bool Prepare() OVERRIDE; 381 virtual void Work() OVERRIDE; 382 383 private: 384 scoped_ptr<core_api::socket::SetNoDelay::Params> params_; 385 }; 386 387 class SocketGetInfoFunction : public SocketAsyncApiFunction { 388 public: 389 DECLARE_EXTENSION_FUNCTION("socket.getInfo", SOCKET_GETINFO) 390 391 SocketGetInfoFunction(); 392 393 protected: 394 virtual ~SocketGetInfoFunction(); 395 396 // AsyncApiFunction: 397 virtual bool Prepare() OVERRIDE; 398 virtual void Work() OVERRIDE; 399 400 private: 401 scoped_ptr<core_api::socket::GetInfo::Params> params_; 402 }; 403 404 class SocketGetNetworkListFunction : public AsyncExtensionFunction { 405 public: 406 DECLARE_EXTENSION_FUNCTION("socket.getNetworkList", SOCKET_GETNETWORKLIST) 407 408 protected: ~SocketGetNetworkListFunction()409 virtual ~SocketGetNetworkListFunction() {} 410 virtual bool RunAsync() OVERRIDE; 411 412 private: 413 void GetNetworkListOnFileThread(); 414 void HandleGetNetworkListError(); 415 void SendResponseOnUIThread(const net::NetworkInterfaceList& interface_list); 416 }; 417 418 class SocketJoinGroupFunction : public SocketAsyncApiFunction { 419 public: 420 DECLARE_EXTENSION_FUNCTION("socket.joinGroup", SOCKET_MULTICAST_JOIN_GROUP) 421 422 SocketJoinGroupFunction(); 423 424 protected: 425 virtual ~SocketJoinGroupFunction(); 426 427 // AsyncApiFunction 428 virtual bool Prepare() OVERRIDE; 429 virtual void Work() OVERRIDE; 430 431 private: 432 scoped_ptr<core_api::socket::JoinGroup::Params> params_; 433 }; 434 435 class SocketLeaveGroupFunction : public SocketAsyncApiFunction { 436 public: 437 DECLARE_EXTENSION_FUNCTION("socket.leaveGroup", SOCKET_MULTICAST_LEAVE_GROUP) 438 439 SocketLeaveGroupFunction(); 440 441 protected: 442 virtual ~SocketLeaveGroupFunction(); 443 444 // AsyncApiFunction 445 virtual bool Prepare() OVERRIDE; 446 virtual void Work() OVERRIDE; 447 448 private: 449 scoped_ptr<core_api::socket::LeaveGroup::Params> params_; 450 }; 451 452 class SocketSetMulticastTimeToLiveFunction : public SocketAsyncApiFunction { 453 public: 454 DECLARE_EXTENSION_FUNCTION("socket.setMulticastTimeToLive", 455 SOCKET_MULTICAST_SET_TIME_TO_LIVE) 456 457 SocketSetMulticastTimeToLiveFunction(); 458 459 protected: 460 virtual ~SocketSetMulticastTimeToLiveFunction(); 461 462 // AsyncApiFunction 463 virtual bool Prepare() OVERRIDE; 464 virtual void Work() OVERRIDE; 465 466 private: 467 scoped_ptr<core_api::socket::SetMulticastTimeToLive::Params> params_; 468 }; 469 470 class SocketSetMulticastLoopbackModeFunction : public SocketAsyncApiFunction { 471 public: 472 DECLARE_EXTENSION_FUNCTION("socket.setMulticastLoopbackMode", 473 SOCKET_MULTICAST_SET_LOOPBACK_MODE) 474 475 SocketSetMulticastLoopbackModeFunction(); 476 477 protected: 478 virtual ~SocketSetMulticastLoopbackModeFunction(); 479 480 // AsyncApiFunction 481 virtual bool Prepare() OVERRIDE; 482 virtual void Work() OVERRIDE; 483 484 private: 485 scoped_ptr<core_api::socket::SetMulticastLoopbackMode::Params> params_; 486 }; 487 488 class SocketGetJoinedGroupsFunction : public SocketAsyncApiFunction { 489 public: 490 DECLARE_EXTENSION_FUNCTION("socket.getJoinedGroups", 491 SOCKET_MULTICAST_GET_JOINED_GROUPS) 492 493 SocketGetJoinedGroupsFunction(); 494 495 protected: 496 virtual ~SocketGetJoinedGroupsFunction(); 497 498 // AsyncApiFunction 499 virtual bool Prepare() OVERRIDE; 500 virtual void Work() OVERRIDE; 501 502 private: 503 scoped_ptr<core_api::socket::GetJoinedGroups::Params> params_; 504 }; 505 } // namespace extensions 506 507 #endif // EXTENSIONS_BROWSER_API_SOCKET_SOCKET_API_H_ 508