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

Side by Side Diff: ppapi/proxy/ppb_tcp_socket_private_proxy.cc

Issue 8688002: PPB_TCPSocket_Private/PPB_UDPSocket_Private are exposed to Browser (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Deleted NaCl tests. Created 9 years 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ppapi/proxy/ppb_tcp_socket_private_proxy.h" 5 #include "ppapi/proxy/ppb_tcp_socket_private_proxy.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
yzshen1 2011/11/28 20:59:16 You could remove those includes that are not neede
ygorshenin 2011/11/29 18:30:09 Done.
8 #include <cstring> 8 #include <cstring>
9 #include <map> 9 #include <map>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
yzshen1 2011/11/29 20:19:32 This is still needed.
yzshen1 2011/11/30 21:11:04 This is still needed, because DCHECK is used in th
ygorshenin 2011/12/01 10:58:31 Restored.
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/task.h" 14 #include "base/task.h"
15 #include "ppapi/c/pp_errors.h" 15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/proxy/plugin_dispatcher.h" 16 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/plugin_resource_tracker.h" 17 #include "ppapi/proxy/plugin_resource_tracker.h"
18 #include "ppapi/proxy/ppapi_messages.h" 18 #include "ppapi/proxy/ppapi_messages.h"
19 #include "ppapi/shared_impl/resource.h" 19 #include "ppapi/shared_impl/resource.h"
20 #include "ppapi/thunk/ppb_tcp_socket_private_api.h" 20 #include "ppapi/shared_impl/tcp_socket_impl.h"
21 #include "ppapi/thunk/thunk.h" 21 #include "ppapi/thunk/thunk.h"
22 22
23 using ppapi::thunk::PPB_TCPSocket_Private_API;
24
25 namespace ppapi { 23 namespace ppapi {
26 namespace proxy { 24 namespace proxy {
27 25
28 const int32_t kTCPSocketMaxReadSize = 1024 * 1024;
29 const int32_t kTCPSocketMaxWriteSize = 1024 * 1024;
30
31 class TCPSocket;
32
33 namespace { 26 namespace {
34 27
35 typedef std::map<uint32, TCPSocket*> IDToSocketMap; 28 typedef std::map<uint32, TCPSocketImpl*> IDToSocketMap;
36 IDToSocketMap* g_id_to_socket = NULL; 29 IDToSocketMap* g_id_to_socket = NULL;
37 30
38 class AbortCallbackTask : public Task { 31 class AbortCallbackTask : public Task {
39 public: 32 public:
40 explicit AbortCallbackTask(PP_CompletionCallback callback) 33 explicit AbortCallbackTask(PP_CompletionCallback callback)
41 : callback_(callback) {} 34 : callback_(callback) {}
42 virtual ~AbortCallbackTask() {} 35 virtual ~AbortCallbackTask() {}
43 virtual void Run() { 36 virtual void Run() {
44 if (callback_.func) 37 if (callback_.func)
45 PP_RunCompletionCallback(&callback_, PP_ERROR_ABORTED); 38 PP_RunCompletionCallback(&callback_, PP_ERROR_ABORTED);
46 } 39 }
47 40
48 private: 41 private:
49 PP_CompletionCallback callback_; 42 PP_CompletionCallback callback_;
50 }; 43 };
51 44
52 } // namespace 45 class TCPSocket : public TCPSocketImpl {
53
54 class TCPSocket : public PPB_TCPSocket_Private_API,
55 public Resource {
56 public: 46 public:
57 TCPSocket(const HostResource& resource, uint32 socket_id); 47 TCPSocket(const HostResource& resource, uint32 socket_id);
58 virtual ~TCPSocket(); 48 virtual ~TCPSocket();
59 49
60 // Resource overrides. 50 virtual void SendConnect(const std::string& host, uint16_t port) OVERRIDE;
61 virtual PPB_TCPSocket_Private_API* AsPPB_TCPSocket_Private_API() OVERRIDE; 51 virtual void SendConnectWithNetAddress(
62 52 const PP_NetAddress_Private& addr) OVERRIDE;
63 // PPB_TCPSocket_Private_API implementation. 53 virtual void SendSSLHandshake(const std::string& server_name,
64 virtual int32_t Connect(const char* host, 54 uint16_t server_port) OVERRIDE;
65 uint16_t port, 55 virtual void SendRead(int32_t bytes_to_read) OVERRIDE;
66 PP_CompletionCallback callback) OVERRIDE; 56 virtual void SendWrite(const std::string& buffer) OVERRIDE;
67 virtual int32_t ConnectWithNetAddress( 57 virtual void SendDisconnect() OVERRIDE;
68 const PP_NetAddress_Private* addr, 58 virtual void PostAbort(PP_CompletionCallback callback) OVERRIDE;
69 PP_CompletionCallback callback) OVERRIDE;
70 virtual PP_Bool GetLocalAddress(PP_NetAddress_Private* local_addr) OVERRIDE;
71 virtual PP_Bool GetRemoteAddress(PP_NetAddress_Private* remote_addr) OVERRIDE;
72 virtual int32_t SSLHandshake(const char* server_name,
73 uint16_t server_port,
74 PP_CompletionCallback callback) OVERRIDE;
75 virtual int32_t Read(char* buffer,
76 int32_t bytes_to_read,
77 PP_CompletionCallback callback) OVERRIDE;
78 virtual int32_t Write(const char* buffer,
79 int32_t bytes_to_write,
80 PP_CompletionCallback callback) OVERRIDE;
81 virtual void Disconnect() OVERRIDE;
82
83 // Notifications from the proxy.
84 void OnConnectCompleted(bool succeeded,
85 const PP_NetAddress_Private& local_addr,
86 const PP_NetAddress_Private& remote_addr);
87 void OnSSLHandshakeCompleted(bool succeeded);
88 void OnReadCompleted(bool succeeded, const std::string& data);
89 void OnWriteCompleted(bool succeeded, int32_t bytes_written);
90 59
91 private: 60 private:
92 enum ConnectionState { 61 void SendToBrowser(IPC::Message* msg);
93 // Before a connection is successfully established (including a connect
94 // request is pending or a previous connect request failed).
95 BEFORE_CONNECT,
96 // A connection has been successfully established (including a request of
97 // initiating SSL is pending).
98 CONNECTED,
99 // An SSL connection has been successfully established.
100 SSL_CONNECTED,
101 // The connection has been ended.
102 DISCONNECTED
103 };
104
105 bool IsConnected() const;
106
107 PluginDispatcher* GetDispatcher() const {
108 return PluginDispatcher::GetForResource(this);
109 }
110
111 // Backend for both Connect() and ConnectWithNetAddress(). To keep things
112 // generic, the message is passed in (on error, it's deleted).
113 int32_t ConnectWithMessage(IPC::Message* msg,
114 PP_CompletionCallback callback);
115
116 void PostAbortAndClearIfNecessary(PP_CompletionCallback* callback);
117
118 uint32 socket_id_;
119 ConnectionState connection_state_;
120
121 PP_CompletionCallback connect_callback_;
122 PP_CompletionCallback ssl_handshake_callback_;
123 PP_CompletionCallback read_callback_;
124 PP_CompletionCallback write_callback_;
125
126 char* read_buffer_;
127 int32_t bytes_to_read_;
128
129 PP_NetAddress_Private local_addr_;
130 PP_NetAddress_Private remote_addr_;
131 62
132 DISALLOW_COPY_AND_ASSIGN(TCPSocket); 63 DISALLOW_COPY_AND_ASSIGN(TCPSocket);
133 }; 64 };
134 65
135 TCPSocket::TCPSocket(const HostResource& resource, uint32 socket_id) 66 TCPSocket::TCPSocket(const HostResource& resource, uint32 socket_id)
136 : Resource(resource), 67 : TCPSocketImpl(resource, socket_id) {
137 socket_id_(socket_id),
138 connection_state_(BEFORE_CONNECT),
139 connect_callback_(PP_BlockUntilComplete()),
140 ssl_handshake_callback_(PP_BlockUntilComplete()),
141 read_callback_(PP_BlockUntilComplete()),
142 write_callback_(PP_BlockUntilComplete()),
143 read_buffer_(NULL),
144 bytes_to_read_(-1) {
145 DCHECK(socket_id != 0);
146
147 local_addr_.size = 0;
148 memset(local_addr_.data, 0, sizeof(local_addr_.data));
149 remote_addr_.size = 0;
150 memset(remote_addr_.data, 0, sizeof(remote_addr_.data));
151
152 if (!g_id_to_socket) 68 if (!g_id_to_socket)
153 g_id_to_socket = new IDToSocketMap(); 69 g_id_to_socket = new IDToSocketMap();
154 DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end()); 70 DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
155 (*g_id_to_socket)[socket_id] = this; 71 (*g_id_to_socket)[socket_id] = this;
156 } 72 }
157 73
158 TCPSocket::~TCPSocket() { 74 TCPSocket::~TCPSocket() {
159 Disconnect(); 75 Disconnect();
76
dmichael (off chromium) 2011/11/28 20:38:43 nit: extra carriage return added
yzshen1 2011/11/28 20:59:16 1) Please remove the empty line.
ygorshenin 2011/11/29 18:30:09 Done.
ygorshenin 2011/11/29 18:30:09 Done.
160 } 77 }
161 78
162 PPB_TCPSocket_Private_API* TCPSocket::AsPPB_TCPSocket_Private_API() { 79 void TCPSocket::SendToBrowser(IPC::Message* msg) {
yzshen1 2011/11/28 20:59:16 Please keep the definitions in the same order as t
ygorshenin 2011/11/29 18:30:09 Done.
163 return this; 80 PluginDispatcher::GetForResource(this)->SendToBrowser(msg);
164 } 81 }
165 82
166 int32_t TCPSocket::Connect(const char* host, 83 void TCPSocket::SendConnect(const std::string& host, uint16_t port) {
167 uint16_t port, 84 SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Connect(socket_id_, host, port));
168 PP_CompletionCallback callback) {
169 if (!host)
170 return PP_ERROR_BADARGUMENT;
171
172 return ConnectWithMessage(
173 new PpapiHostMsg_PPBTCPSocket_Connect(socket_id_, host, port),
174 callback);
175 } 85 }
176 86
177 int32_t TCPSocket::ConnectWithNetAddress( 87 void TCPSocket::SendConnectWithNetAddress(const PP_NetAddress_Private& addr) {
178 const PP_NetAddress_Private* addr, 88 SendToBrowser(
179 PP_CompletionCallback callback) { 89 new PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress(socket_id_, addr));
180 if (!addr)
181 return PP_ERROR_BADARGUMENT;
182
183 return ConnectWithMessage(
184 new PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress(
185 socket_id_, *addr),
186 callback);
187 } 90 }
188 91
189 PP_Bool TCPSocket::GetLocalAddress(PP_NetAddress_Private* local_addr) { 92 void TCPSocket::SendSSLHandshake(const std::string& server_name,
190 if (!IsConnected() || !local_addr) 93 uint16_t server_port) {
yzshen1 2011/11/28 20:59:16 Wrong indent.
ygorshenin 2011/11/29 18:30:09 Done.
191 return PP_FALSE; 94 SendToBrowser(new PpapiHostMsg_PPBTCPSocket_SSLHandshake(
192 95 socket_id_, server_name, server_port));
193 *local_addr = local_addr_;
194 return PP_TRUE;
195 } 96 }
196 97
197 PP_Bool TCPSocket::GetRemoteAddress(PP_NetAddress_Private* remote_addr) { 98 void TCPSocket::SendRead(int32_t bytes_to_read) {
198 if (!IsConnected() || !remote_addr) 99 SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Read(socket_id_, bytes_to_read));
199 return PP_FALSE;
200
201 *remote_addr = remote_addr_;
202 return PP_TRUE;
203 } 100 }
204 101
205 int32_t TCPSocket::SSLHandshake(const char* server_name, 102 void TCPSocket::SendWrite(const std::string& buffer) {
206 uint16_t server_port, 103 SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Write(socket_id_, buffer));
207 PP_CompletionCallback callback) {
208 if (!server_name)
209 return PP_ERROR_BADARGUMENT;
210 if (!callback.func)
211 return PP_ERROR_BLOCKS_MAIN_THREAD;
212
213 if (connection_state_ != CONNECTED)
214 return PP_ERROR_FAILED;
215 if (ssl_handshake_callback_.func || read_callback_.func ||
216 write_callback_.func)
217 return PP_ERROR_INPROGRESS;
218
219 ssl_handshake_callback_ = callback;
220
221 // Send the request, the browser will call us back via SSLHandshakeACK.
222 GetDispatcher()->SendToBrowser(
223 new PpapiHostMsg_PPBTCPSocket_SSLHandshake(
224 socket_id_, std::string(server_name), server_port));
225 return PP_OK_COMPLETIONPENDING;
226 } 104 }
227 105
228 int32_t TCPSocket::Read(char* buffer, 106 void TCPSocket::SendDisconnect() {
229 int32_t bytes_to_read,
230 PP_CompletionCallback callback) {
231 if (!buffer || bytes_to_read <= 0)
232 return PP_ERROR_BADARGUMENT;
233 if (!callback.func)
234 return PP_ERROR_BLOCKS_MAIN_THREAD;
235
236 if (!IsConnected())
237 return PP_ERROR_FAILED;
238 if (read_callback_.func || ssl_handshake_callback_.func)
239 return PP_ERROR_INPROGRESS;
240
241 read_buffer_ = buffer;
242 bytes_to_read_ = std::min(bytes_to_read, kTCPSocketMaxReadSize);
243 read_callback_ = callback;
244
245 // Send the request, the browser will call us back via ReadACK.
246 GetDispatcher()->SendToBrowser(
247 new PpapiHostMsg_PPBTCPSocket_Read(socket_id_, bytes_to_read_));
248 return PP_OK_COMPLETIONPENDING;
249 }
250
251 int32_t TCPSocket::Write(const char* buffer,
252 int32_t bytes_to_write,
253 PP_CompletionCallback callback) {
254 if (!buffer || bytes_to_write <= 0)
255 return PP_ERROR_BADARGUMENT;
256 if (!callback.func)
257 return PP_ERROR_BLOCKS_MAIN_THREAD;
258
259 if (!IsConnected())
260 return PP_ERROR_FAILED;
261 if (write_callback_.func || ssl_handshake_callback_.func)
262 return PP_ERROR_INPROGRESS;
263
264 if (bytes_to_write > kTCPSocketMaxWriteSize)
265 bytes_to_write = kTCPSocketMaxWriteSize;
266
267 write_callback_ = callback;
268
269 // Send the request, the browser will call us back via WriteACK.
270 GetDispatcher()->SendToBrowser(
271 new PpapiHostMsg_PPBTCPSocket_Write(
272 socket_id_, std::string(buffer, bytes_to_write)));
273 return PP_OK_COMPLETIONPENDING;
274 }
275
276 void TCPSocket::Disconnect() {
277 if (connection_state_ == DISCONNECTED)
278 return;
279
280 connection_state_ = DISCONNECTED;
281 // After removed from the mapping, this object won't receive any notifications 107 // After removed from the mapping, this object won't receive any notifications
282 // from the proxy. 108 // from the proxy.
283 DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end()); 109 DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end());
284 g_id_to_socket->erase(socket_id_); 110 g_id_to_socket->erase(socket_id_);
285 111 SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_));
286 GetDispatcher()->SendToBrowser(
287 new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_));
288 socket_id_ = 0;
289
290 PostAbortAndClearIfNecessary(&connect_callback_);
291 PostAbortAndClearIfNecessary(&ssl_handshake_callback_);
292 PostAbortAndClearIfNecessary(&read_callback_);
293 PostAbortAndClearIfNecessary(&write_callback_);
294 read_buffer_ = NULL;
295 bytes_to_read_ = -1;
296 } 112 }
297 113
298 void TCPSocket::OnConnectCompleted( 114 void TCPSocket::PostAbort(PP_CompletionCallback callback) {
299 bool succeeded, 115 MessageLoop::current()->PostTask(FROM_HERE, new AbortCallbackTask(callback));
dmichael (off chromium) 2011/11/28 20:38:43 It looks like you could pretty easily replace Abor
ygorshenin 2011/11/29 18:30:09 Added TODO comment.
300 const PP_NetAddress_Private& local_addr,
301 const PP_NetAddress_Private& remote_addr) {
302 if (connection_state_ != BEFORE_CONNECT || !connect_callback_.func) {
303 NOTREACHED();
304 return;
305 }
306
307 if (succeeded) {
308 local_addr_ = local_addr;
309 remote_addr_ = remote_addr;
310 connection_state_ = CONNECTED;
311 }
312 PP_RunAndClearCompletionCallback(&connect_callback_,
313 succeeded ? PP_OK : PP_ERROR_FAILED);
314 } 116 }
315 117
316 void TCPSocket::OnSSLHandshakeCompleted(bool succeeded) { 118 } // namespace
317 if (connection_state_ != CONNECTED || !ssl_handshake_callback_.func) {
318 NOTREACHED();
319 return;
320 }
321 119
322 if (succeeded) { 120 //------------------------------------------------------------------------------
323 connection_state_ = SSL_CONNECTED;
324 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_OK);
325 } else {
326 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_ERROR_FAILED);
327 Disconnect();
328 }
329 }
330
331 void TCPSocket::OnReadCompleted(bool succeeded, const std::string& data) {
332 if (!read_callback_.func || !read_buffer_) {
333 NOTREACHED();
334 return;
335 }
336
337 if (succeeded) {
338 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
339 if (!data.empty())
340 memcpy(read_buffer_, data.c_str(), data.size());
341 }
342 read_buffer_ = NULL;
343 bytes_to_read_ = -1;
344
345 PP_RunAndClearCompletionCallback(
346 &read_callback_,
347 succeeded ? static_cast<int32_t>(data.size()) :
348 static_cast<int32_t>(PP_ERROR_FAILED));
349 }
350
351 void TCPSocket::OnWriteCompleted(bool succeeded, int32_t bytes_written) {
352 if (!write_callback_.func || (succeeded && bytes_written < 0)) {
353 NOTREACHED();
354 return;
355 }
356
357 PP_RunAndClearCompletionCallback(
358 &write_callback_,
359 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
360 }
361
362 bool TCPSocket::IsConnected() const {
363 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
364 }
365
366 int32_t TCPSocket::ConnectWithMessage(IPC::Message* msg,
367 PP_CompletionCallback callback) {
368 scoped_ptr<IPC::Message> msg_deletor(msg);
369 if (!callback.func)
370 return PP_ERROR_BLOCKS_MAIN_THREAD;
371 if (connection_state_ != BEFORE_CONNECT)
372 return PP_ERROR_FAILED;
373 if (connect_callback_.func)
374 return PP_ERROR_INPROGRESS; // Can only have one pending request.
375
376 connect_callback_ = callback;
377 // Send the request, the browser will call us back via ConnectACK.
378 GetDispatcher()->SendToBrowser(msg_deletor.release());
379 return PP_OK_COMPLETIONPENDING;
380 }
381
382 void TCPSocket::PostAbortAndClearIfNecessary(
383 PP_CompletionCallback* callback) {
384 DCHECK(callback);
385
386 if (callback->func) {
387 MessageLoop::current()->PostTask(FROM_HERE,
388 new AbortCallbackTask(*callback));
389 *callback = PP_BlockUntilComplete();
390 }
391 }
392 121
393 PPB_TCPSocket_Private_Proxy::PPB_TCPSocket_Private_Proxy(Dispatcher* dispatcher) 122 PPB_TCPSocket_Private_Proxy::PPB_TCPSocket_Private_Proxy(Dispatcher* dispatcher)
394 : InterfaceProxy(dispatcher) { 123 : InterfaceProxy(dispatcher) {
395 } 124 }
396 125
397 PPB_TCPSocket_Private_Proxy::~PPB_TCPSocket_Private_Proxy() { 126 PPB_TCPSocket_Private_Proxy::~PPB_TCPSocket_Private_Proxy() {
398 } 127 }
399 128
400 // static 129 // static
401 PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResource( 130 PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResource(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 return; 212 return;
484 } 213 }
485 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); 214 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
486 if (iter == g_id_to_socket->end()) 215 if (iter == g_id_to_socket->end())
487 return; 216 return;
488 iter->second->OnWriteCompleted(succeeded, bytes_written); 217 iter->second->OnWriteCompleted(succeeded, bytes_written);
489 } 218 }
490 219
491 } // namespace proxy 220 } // namespace proxy
492 } // namespace ppapi 221 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698