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

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

Issue 22923014: TCPSockets are switched to the new Pepper proxy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync. Created 7 years, 4 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/shared_impl/tcp_socket_shared.h" 5 #include "ppapi/proxy/tcp_socket_resource_base.h"
6 6
7 #include <string.h> 7 #include <cstring>
8 8
9 #include <algorithm>
10
11 #include "base/basictypes.h"
12 #include "base/bind.h"
yzshen1 2013/08/16 20:40:42 Things like bind, logging are still needed, right?
ygorshenin1 2013/08/19 14:33:35 Done.
13 #include "base/logging.h"
14 #include "ppapi/c/pp_bool.h"
15 #include "ppapi/c/pp_completion_callback.h"
16 #include "ppapi/c/pp_errors.h" 9 #include "ppapi/c/pp_errors.h"
17 #include "ppapi/shared_impl/ppapi_globals.h" 10 #include "ppapi/proxy/pp_utils.h"
11 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" 12 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
19 #include "ppapi/shared_impl/socket_option_data.h" 13 #include "ppapi/shared_impl/socket_option_data.h"
14 #include "ppapi/shared_impl/var.h"
20 #include "ppapi/shared_impl/var_tracker.h" 15 #include "ppapi/shared_impl/var_tracker.h"
21 #include "ppapi/shared_impl/var.h"
22 #include "ppapi/thunk/enter.h" 16 #include "ppapi/thunk/enter.h"
23 #include "ppapi/thunk/ppb_x509_certificate_private_api.h"
24 17
25 namespace ppapi { 18 namespace ppapi {
19 namespace proxy {
26 20
27 const int32_t TCPSocketShared::kMaxReadSize = 1024 * 1024; 21 const int32_t TCPSocketResourceBase::kMaxReadSize = 1024 * 1024;
28 const int32_t TCPSocketShared::kMaxWriteSize = 1024 * 1024; 22 const int32_t TCPSocketResourceBase::kMaxWriteSize = 1024 * 1024;
29 const int32_t TCPSocketShared::kMaxSendBufferSize = 23 const int32_t TCPSocketResourceBase::kMaxSendBufferSize =
30 1024 * TCPSocketShared::kMaxWriteSize; 24 1024 * TCPSocketResourceBase::kMaxWriteSize;
31 const int32_t TCPSocketShared::kMaxReceiveBufferSize = 25 const int32_t TCPSocketResourceBase::kMaxReceiveBufferSize =
32 1024 * TCPSocketShared::kMaxReadSize; 26 1024 * TCPSocketResourceBase::kMaxReadSize;
33 27
34 TCPSocketShared::TCPSocketShared(ResourceObjectType resource_type, 28 TCPSocketResourceBase::TCPSocketResourceBase(Connection connection,
35 uint32 socket_id) 29 PP_Instance instance,
36 : resource_type_(resource_type) { 30 bool private_api)
37 Init(socket_id); 31 : PluginResource(connection, instance),
32 connection_state_(BEFORE_CONNECT),
33 read_buffer_(NULL),
34 bytes_to_read_(-1),
35 private_api_(private_api) {
36 local_addr_.size = 0;
37 memset(local_addr_.data, 0,
38 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
39 remote_addr_.size = 0;
40 memset(remote_addr_.data, 0,
41 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
38 } 42 }
39 43
40 TCPSocketShared::~TCPSocketShared() { 44 TCPSocketResourceBase::TCPSocketResourceBase(
45 Connection connection,
46 PP_Instance instance,
47 bool private_api,
48 const PP_NetAddress_Private& local_addr,
49 const PP_NetAddress_Private& remote_addr)
50 : PluginResource(connection, instance),
51 connection_state_(CONNECTED),
52 read_buffer_(NULL),
53 bytes_to_read_(-1),
54 private_api_(private_api) {
55 local_addr_ = local_addr_;
yzshen1 2013/08/16 20:40:42 You used the wrong variable name. Besides, you cou
ygorshenin1 2013/08/19 14:33:35 Done. Tests for TCPServerSocket handle this now.
56 remote_addr_ = remote_addr_;
yzshen1 2013/08/16 20:40:42 You used the wrong variable name.
ygorshenin1 2013/08/19 14:33:35 Done.
41 } 57 }
42 58
43 void TCPSocketShared::OnConnectCompleted( 59 TCPSocketResourceBase::~TCPSocketResourceBase() {
44 int32_t result,
45 const PP_NetAddress_Private& local_addr,
46 const PP_NetAddress_Private& remote_addr) {
47 // It is possible that |connect_callback_| is pending while
48 // |connection_state_| is not BEFORE_CONNECT: DisconnectImpl() has been
49 // called, but a ConnectCompleted notification came earlier than the task to
50 // abort |connect_callback_|. We don't want to update |connection_state_| or
51 // other members in that case.
52 if (connection_state_ != BEFORE_CONNECT ||
53 !TrackedCallback::IsPending(connect_callback_)) {
54 return;
55 }
56
57 result = OverridePPError(result);
58 if (result == PP_OK) {
59 local_addr_ = local_addr;
60 remote_addr_ = remote_addr;
61 connection_state_ = CONNECTED;
62 }
63 connect_callback_->Run(result);
64 } 60 }
65 61
66 void TCPSocketShared::OnSSLHandshakeCompleted( 62 int32_t TCPSocketResourceBase::ConnectImpl(
67 bool succeeded, 63 const char* host,
68 const PPB_X509Certificate_Fields& certificate_fields) { 64 uint16_t port,
69 // It is possible that |ssl_handshake_callback_| is pending while 65 scoped_refptr<TrackedCallback> callback) {
70 // |connection_state_| is not CONNECT: DisconnectImpl() has been
71 // called, but a SSLHandshakeCompleted notification came earlier than the task
72 // to abort |ssl_handshake_callback_|. We don't want to update
73 // |connection_state_| or other members in that case.
74 if (connection_state_ != CONNECTED ||
75 !TrackedCallback::IsPending(ssl_handshake_callback_)) {
76 return;
77 }
78
79 if (succeeded) {
80 connection_state_ = SSL_CONNECTED;
81 server_certificate_ = new PPB_X509Certificate_Private_Shared(
82 resource_type_,
83 GetOwnerResource()->pp_instance(),
84 certificate_fields);
85 ssl_handshake_callback_->Run(PP_OK);
86 } else {
87 // The resource might be released in the callback so we need to hold
88 // a reference so we can Disconnect() first.
89 GetOwnerResource()->AddRef();
90 ssl_handshake_callback_->Run(PP_ERROR_FAILED);
91 DisconnectImpl();
92 GetOwnerResource()->Release();
93 }
94 }
95
96 void TCPSocketShared::OnReadCompleted(int32_t result,
97 const std::string& data) {
98 // It is possible that |read_callback_| is pending while |read_buffer_| is
99 // NULL: DisconnectImpl() has been called, but a ReadCompleted notification
100 // came earlier than the task to abort |read_callback_|. We shouldn't access
101 // the buffer in that case. The user may have released it.
102 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_)
103 return;
104
105 result = OverridePPError(result);
106 bool succeeded = result == PP_OK;
107 if (succeeded) {
108 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
109 if (!data.empty())
110 memcpy(read_buffer_, data.c_str(), data.size());
111 }
112 read_buffer_ = NULL;
113 bytes_to_read_ = -1;
114
115 read_callback_->Run(
116 succeeded ? static_cast<int32_t>(data.size()) : result);
117 }
118
119 void TCPSocketShared::OnWriteCompleted(int32_t result) {
120 if (!TrackedCallback::IsPending(write_callback_))
121 return;
122
123 result = OverridePPError(result);
124 write_callback_->Run(result);
125 }
126
127 void TCPSocketShared::OnSetOptionCompleted(int32_t result) {
128 if (set_option_callbacks_.empty()) {
129 NOTREACHED();
130 return;
131 }
132
133 result = OverridePPError(result);
134 scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front();
135 set_option_callbacks_.pop();
136
137 if (TrackedCallback::IsPending(callback))
138 callback->Run(result);
139 }
140
141 int32_t TCPSocketShared::OverridePPError(int32_t pp_error) {
142 return pp_error;
143 }
144
145 int32_t TCPSocketShared::ConnectImpl(const char* host,
146 uint16_t port,
147 scoped_refptr<TrackedCallback> callback) {
148 if (!host) 66 if (!host)
149 return PP_ERROR_BADARGUMENT; 67 return PP_ERROR_BADARGUMENT;
150 if (connection_state_ != BEFORE_CONNECT) 68 if (connection_state_ != BEFORE_CONNECT)
151 return PP_ERROR_FAILED; 69 return PP_ERROR_FAILED;
152 if (TrackedCallback::IsPending(connect_callback_)) 70 if (TrackedCallback::IsPending(connect_callback_))
153 return PP_ERROR_INPROGRESS; // Can only have one pending request. 71 return PP_ERROR_INPROGRESS; // Can only have one pending request.
154 72
155 connect_callback_ = callback; 73 connect_callback_ = callback;
156 // Send the request, the browser will call us back via ConnectACK. 74
157 SendConnect(host, port); 75 Call<PpapiPluginMsg_TCPSocket_ConnectReply>(
76 BROWSER,
77 PpapiHostMsg_TCPSocket_Connect(host, port),
78 base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply,
79 base::Unretained(this)));
158 return PP_OK_COMPLETIONPENDING; 80 return PP_OK_COMPLETIONPENDING;
159 } 81 }
160 82
161 int32_t TCPSocketShared::ConnectWithNetAddressImpl( 83 int32_t TCPSocketResourceBase::ConnectWithNetAddressImpl(
162 const PP_NetAddress_Private* addr, 84 const PP_NetAddress_Private* addr,
163 scoped_refptr<TrackedCallback> callback) { 85 scoped_refptr<TrackedCallback> callback) {
164 if (!addr) 86 if (!addr)
165 return PP_ERROR_BADARGUMENT; 87 return PP_ERROR_BADARGUMENT;
166 if (connection_state_ != BEFORE_CONNECT) 88 if (connection_state_ != BEFORE_CONNECT)
167 return PP_ERROR_FAILED; 89 return PP_ERROR_FAILED;
168 if (TrackedCallback::IsPending(connect_callback_)) 90 if (TrackedCallback::IsPending(connect_callback_))
169 return PP_ERROR_INPROGRESS; // Can only have one pending request. 91 return PP_ERROR_INPROGRESS; // Can only have one pending request.
170 92
171 connect_callback_ = callback; 93 connect_callback_ = callback;
172 // Send the request, the browser will call us back via ConnectACK. 94
173 SendConnectWithNetAddress(*addr); 95 Call<PpapiPluginMsg_TCPSocket_ConnectReply>(
96 BROWSER,
97 PpapiHostMsg_TCPSocket_ConnectWithNetAddress(*addr),
98 base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply,
99 base::Unretained(this)));
174 return PP_OK_COMPLETIONPENDING; 100 return PP_OK_COMPLETIONPENDING;
175 } 101 }
176 102
177 PP_Bool TCPSocketShared::GetLocalAddressImpl( 103 PP_Bool TCPSocketResourceBase::GetLocalAddressImpl(
178 PP_NetAddress_Private* local_addr) { 104 PP_NetAddress_Private* local_addr) {
179 if (!IsConnected() || !local_addr) 105 if (!IsConnected() || !local_addr)
180 return PP_FALSE; 106 return PP_FALSE;
181
182 *local_addr = local_addr_; 107 *local_addr = local_addr_;
183 return PP_TRUE; 108 return PP_TRUE;
184 } 109 }
185 110
186 PP_Bool TCPSocketShared::GetRemoteAddressImpl( 111 PP_Bool TCPSocketResourceBase::GetRemoteAddressImpl(
187 PP_NetAddress_Private* remote_addr) { 112 PP_NetAddress_Private* remote_addr) {
188 if (!IsConnected() || !remote_addr) 113 if (!IsConnected() || !remote_addr)
189 return PP_FALSE; 114 return PP_FALSE;
190
191 *remote_addr = remote_addr_; 115 *remote_addr = remote_addr_;
192 return PP_TRUE; 116 return PP_TRUE;
193 } 117 }
194 118
195 int32_t TCPSocketShared::SSLHandshakeImpl( 119 int32_t TCPSocketResourceBase::SSLHandshakeImpl(
196 const char* server_name, 120 const char* server_name,
197 uint16_t server_port, 121 uint16_t server_port,
198 scoped_refptr<TrackedCallback> callback) { 122 scoped_refptr<TrackedCallback> callback) {
199 if (!server_name) 123 if (!server_name)
200 return PP_ERROR_BADARGUMENT; 124 return PP_ERROR_BADARGUMENT;
201 125
202 if (connection_state_ != CONNECTED) 126 if (connection_state_ != CONNECTED)
203 return PP_ERROR_FAILED; 127 return PP_ERROR_FAILED;
204 if (TrackedCallback::IsPending(ssl_handshake_callback_) || 128 if (TrackedCallback::IsPending(ssl_handshake_callback_) ||
205 TrackedCallback::IsPending(read_callback_) || 129 TrackedCallback::IsPending(read_callback_) ||
206 TrackedCallback::IsPending(write_callback_)) 130 TrackedCallback::IsPending(write_callback_)) {
207 return PP_ERROR_INPROGRESS; 131 return PP_ERROR_INPROGRESS;
132 }
208 133
209 ssl_handshake_callback_ = callback; 134 ssl_handshake_callback_ = callback;
210 135
211 // Send the request, the browser will call us back via SSLHandshakeACK. 136 Call<PpapiPluginMsg_TCPSocket_SSLHandshakeReply>(
212 SendSSLHandshake(server_name, server_port, trusted_certificates_, 137 BROWSER,
213 untrusted_certificates_); 138 PpapiHostMsg_TCPSocket_SSLHandshake(server_name,
139 server_port,
140 trusted_certificates_,
141 untrusted_certificates_),
142 base::Bind(&TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply,
143 base::Unretained(this)));
214 return PP_OK_COMPLETIONPENDING; 144 return PP_OK_COMPLETIONPENDING;
215 } 145 }
216 146
217 PP_Resource TCPSocketShared::GetServerCertificateImpl() { 147 PP_Resource TCPSocketResourceBase::GetServerCertificateImpl() {
218 if (!server_certificate_.get()) 148 if (!server_certificate_.get())
219 return 0; 149 return 0;
220 return server_certificate_->GetReference(); 150 return server_certificate_->GetReference();
221 } 151 }
222 152
223 PP_Bool TCPSocketShared::AddChainBuildingCertificateImpl( 153 PP_Bool TCPSocketResourceBase::AddChainBuildingCertificateImpl(
224 PP_Resource certificate, 154 PP_Resource certificate,
225 PP_Bool trusted) { 155 PP_Bool trusted) {
226 // TODO(raymes): The plumbing for this functionality is implemented but the 156 // TODO(raymes): The plumbing for this functionality is implemented but the
227 // certificates aren't yet used for the connection, so just return false for 157 // certificates aren't yet used for the connection, so just return false for
228 // now. 158 // now.
229 return PP_FALSE; 159 return PP_FALSE;
230 160
231 thunk::EnterResourceNoLock<thunk::PPB_X509Certificate_Private_API> 161 thunk::EnterResourceNoLock<thunk::PPB_X509Certificate_Private_API>
232 enter_cert(certificate, true); 162 enter_cert(certificate, true);
233 if (enter_cert.failed()) 163 if (enter_cert.failed())
(...skipping 10 matching lines...) Expand all
244 if (PP_ToBool(trusted)) 174 if (PP_ToBool(trusted))
245 trusted_certificates_.push_back(der); 175 trusted_certificates_.push_back(der);
246 else 176 else
247 untrusted_certificates_.push_back(der); 177 untrusted_certificates_.push_back(der);
248 success = PP_TRUE; 178 success = PP_TRUE;
249 } 179 }
250 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(der_var); 180 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(der_var);
251 return success; 181 return success;
252 } 182 }
253 183
254 int32_t TCPSocketShared::ReadImpl(char* buffer, 184 int32_t TCPSocketResourceBase::ReadImpl(
255 int32_t bytes_to_read, 185 char* buffer,
256 scoped_refptr<TrackedCallback> callback) { 186 int32_t bytes_to_read,
187 scoped_refptr<TrackedCallback> callback) {
257 if (!buffer || bytes_to_read <= 0) 188 if (!buffer || bytes_to_read <= 0)
258 return PP_ERROR_BADARGUMENT; 189 return PP_ERROR_BADARGUMENT;
259 190
260 if (!IsConnected()) 191 if (!IsConnected())
261 return PP_ERROR_FAILED; 192 return PP_ERROR_FAILED;
262 if (TrackedCallback::IsPending(read_callback_) || 193 if (TrackedCallback::IsPending(read_callback_) ||
263 TrackedCallback::IsPending(ssl_handshake_callback_)) 194 TrackedCallback::IsPending(ssl_handshake_callback_))
264 return PP_ERROR_INPROGRESS; 195 return PP_ERROR_INPROGRESS;
265 read_buffer_ = buffer; 196 read_buffer_ = buffer;
266 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize); 197 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize);
267 read_callback_ = callback; 198 read_callback_ = callback;
268 199
269 // Send the request, the browser will call us back via ReadACK. 200 Call<PpapiPluginMsg_TCPSocket_ReadReply>(
270 SendRead(bytes_to_read_); 201 BROWSER,
202 PpapiHostMsg_TCPSocket_Read(bytes_to_read),
yzshen1 2013/08/16 20:40:42 you used the wrong variable name.
ygorshenin1 2013/08/19 14:33:35 Done, now test for TCPSocketPrivate handles this.
203 base::Bind(&TCPSocketResourceBase::OnPluginMsgReadReply,
204 base::Unretained(this)));
271 return PP_OK_COMPLETIONPENDING; 205 return PP_OK_COMPLETIONPENDING;
272 } 206 }
273 207
274 int32_t TCPSocketShared::WriteImpl(const char* buffer, 208 int32_t TCPSocketResourceBase::WriteImpl(
275 int32_t bytes_to_write, 209 const char* buffer,
276 scoped_refptr<TrackedCallback> callback) { 210 int32_t bytes_to_write,
211 scoped_refptr<TrackedCallback> callback) {
277 if (!buffer || bytes_to_write <= 0) 212 if (!buffer || bytes_to_write <= 0)
278 return PP_ERROR_BADARGUMENT; 213 return PP_ERROR_BADARGUMENT;
279 214
280 if (!IsConnected()) 215 if (!IsConnected())
281 return PP_ERROR_FAILED; 216 return PP_ERROR_FAILED;
282 if (TrackedCallback::IsPending(write_callback_) || 217 if (TrackedCallback::IsPending(write_callback_) ||
283 TrackedCallback::IsPending(ssl_handshake_callback_)) 218 TrackedCallback::IsPending(ssl_handshake_callback_))
284 return PP_ERROR_INPROGRESS; 219 return PP_ERROR_INPROGRESS;
285 220
286 if (bytes_to_write > kMaxWriteSize) 221 if (bytes_to_write > kMaxWriteSize)
287 bytes_to_write = kMaxWriteSize; 222 bytes_to_write = kMaxWriteSize;
288 223
289 write_callback_ = callback; 224 write_callback_ = callback;
290 225
291 // Send the request, the browser will call us back via WriteACK. 226 Call<PpapiPluginMsg_TCPSocket_WriteReply>(
292 SendWrite(std::string(buffer, bytes_to_write)); 227 BROWSER,
228 PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)),
229 base::Bind(&TCPSocketResourceBase::OnPluginMsgWriteReply,
230 base::Unretained(this)));
293 return PP_OK_COMPLETIONPENDING; 231 return PP_OK_COMPLETIONPENDING;
294 } 232 }
295 233
296 void TCPSocketShared::DisconnectImpl() { 234 void TCPSocketResourceBase::DisconnectImpl() {
297 if (connection_state_ == DISCONNECTED) 235 if (connection_state_ == DISCONNECTED)
298 return; 236 return;
299 237
300 connection_state_ = DISCONNECTED; 238 connection_state_ = DISCONNECTED;
301 239
302 SendDisconnect(); 240 Post(BROWSER, PpapiHostMsg_TCPSocket_Disconnect());
303 socket_id_ = 0;
304 241
305 PostAbortIfNecessary(&connect_callback_); 242 PostAbortIfNecessary(&connect_callback_);
306 PostAbortIfNecessary(&ssl_handshake_callback_); 243 PostAbortIfNecessary(&ssl_handshake_callback_);
307 PostAbortIfNecessary(&read_callback_); 244 PostAbortIfNecessary(&read_callback_);
308 PostAbortIfNecessary(&write_callback_); 245 PostAbortIfNecessary(&write_callback_);
309 read_buffer_ = NULL; 246 read_buffer_ = NULL;
310 bytes_to_read_ = -1; 247 bytes_to_read_ = -1;
311 server_certificate_ = NULL; 248 server_certificate_ = NULL;
312 } 249 }
313 250
314 int32_t TCPSocketShared::SetOptionImpl( 251 int32_t TCPSocketResourceBase::SetOptionImpl(
315 PP_TCPSocket_Option name, 252 PP_TCPSocket_Option name,
316 const PP_Var& value, 253 const PP_Var& value,
317 scoped_refptr<TrackedCallback> callback) { 254 scoped_refptr<TrackedCallback> callback) {
318 if (!IsConnected()) 255 if (!IsConnected())
319 return PP_ERROR_FAILED; 256 return PP_ERROR_FAILED;
320 257
321 SocketOptionData option_data; 258 SocketOptionData option_data;
322 switch (name) { 259 switch (name) {
323 case PP_TCPSOCKET_OPTION_NO_DELAY: { 260 case PP_TCPSOCKET_OPTION_NO_DELAY: {
324 if (value.type != PP_VARTYPE_BOOL) 261 if (value.type != PP_VARTYPE_BOOL)
325 return PP_ERROR_BADARGUMENT; 262 return PP_ERROR_BADARGUMENT;
326 option_data.SetBool(PP_ToBool(value.value.as_bool)); 263 option_data.SetBool(PP_ToBool(value.value.as_bool));
327 break; 264 break;
328 } 265 }
329 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 266 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE:
330 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 267 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
331 if (value.type != PP_VARTYPE_INT32) 268 if (value.type != PP_VARTYPE_INT32)
332 return PP_ERROR_BADARGUMENT; 269 return PP_ERROR_BADARGUMENT;
333 option_data.SetInt32(value.value.as_int); 270 option_data.SetInt32(value.value.as_int);
334 break; 271 break;
335 } 272 }
336 default: { 273 default: {
337 NOTREACHED(); 274 NOTREACHED();
338 return PP_ERROR_BADARGUMENT; 275 return PP_ERROR_BADARGUMENT;
339 } 276 }
340 } 277 }
341 278
342 set_option_callbacks_.push(callback); 279 set_option_callbacks_.push(callback);
343 SendSetOption(name, option_data); 280
281 Call<PpapiPluginMsg_TCPSocket_SetOptionReply>(
282 BROWSER,
283 PpapiHostMsg_TCPSocket_SetOption(name, option_data),
284 base::Bind(&TCPSocketResourceBase::OnPluginMsgSetOptionReply,
285 base::Unretained(this)));
344 return PP_OK_COMPLETIONPENDING; 286 return PP_OK_COMPLETIONPENDING;
345 } 287 }
346 288
347 void TCPSocketShared::Init(uint32 socket_id) { 289 bool TCPSocketResourceBase::IsConnected() const {
348 DCHECK(socket_id != 0);
349 socket_id_ = socket_id;
350 connection_state_ = BEFORE_CONNECT;
351 read_buffer_ = NULL;
352 bytes_to_read_ = -1;
353
354 local_addr_.size = 0;
355 memset(local_addr_.data, 0,
356 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
357 remote_addr_.size = 0;
358 memset(remote_addr_.data, 0,
359 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
360 }
361
362 bool TCPSocketShared::IsConnected() const {
363 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED; 290 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
364 } 291 }
365 292
366 void TCPSocketShared::PostAbortIfNecessary( 293 void TCPSocketResourceBase::PostAbortIfNecessary(
367 scoped_refptr<TrackedCallback>* callback) { 294 scoped_refptr<TrackedCallback>* callback) {
368 if (TrackedCallback::IsPending(*callback)) 295 if (TrackedCallback::IsPending(*callback))
369 (*callback)->PostAbort(); 296 (*callback)->PostAbort();
370 } 297 }
371 298
299 void TCPSocketResourceBase::OnPluginMsgConnectReply(
300 const ResourceMessageReplyParams& params,
301 const PP_NetAddress_Private& local_addr,
302 const PP_NetAddress_Private& remote_addr) {
303 // It is possible that |connect_callback_| is pending while
304 // |connection_state_| is not BEFORE_CONNECT: DisconnectImpl() has been
305 // called, but a ConnectCompleted notification came earlier than the task to
306 // abort |connect_callback_|. We don't want to update |connection_state_| or
307 // other members in that case.
308 if (connection_state_ != BEFORE_CONNECT ||
309 !TrackedCallback::IsPending(connect_callback_)) {
310 return;
311 }
312
313 if (params.result() == PP_OK) {
314 local_addr_ = local_addr;
315 remote_addr_ = remote_addr;
316 connection_state_ = CONNECTED;
317 }
318 RunCallback(connect_callback_, params.result());
319 }
320
321 void TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply(
322 const ResourceMessageReplyParams& params,
323 const PPB_X509Certificate_Fields& certificate_fields) {
324 // It is possible that |ssl_handshake_callback_| is pending while
yzshen1 2013/08/16 20:40:42 wrong indent.
ygorshenin1 2013/08/19 14:33:35 Done.
325 // |connection_state_| is not CONNECT: DisconnectImpl() has been
326 // called, but a SSLHandshakeCompleted notification came earlier than the task
327 // to abort |ssl_handshake_callback_|. We don't want to update
328 // |connection_state_| or other members in that case.
329 if (connection_state_ != CONNECTED ||
330 !TrackedCallback::IsPending(ssl_handshake_callback_)) {
331 return;
332 }
333
334 if (params.result() == PP_OK) {
335 connection_state_ = SSL_CONNECTED;
336 server_certificate_ = new PPB_X509Certificate_Private_Shared(
337 OBJECT_IS_PROXY,
338 pp_instance(),
339 certificate_fields);
340 RunCallback(ssl_handshake_callback_, params.result());
341 } else {
342 // The resource might be released in the callback so we need to hold
343 // a reference so we can Disconnect() first.
344 AddRef();
345 RunCallback(ssl_handshake_callback_, params.result());
346 DisconnectImpl();
347 Release();
348 }
349 }
350
351 void TCPSocketResourceBase::OnPluginMsgReadReply(
352 const ResourceMessageReplyParams& params,
353 const std::string& data) {
354 // It is possible that |read_callback_| is pending while |read_buffer_| is
355 // NULL: DisconnectImpl() has been called, but a ReadCompleted notification
356 // came earlier than the task to abort |read_callback_|. We shouldn't access
357 // the buffer in that case. The user may have released it.
358 if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_)
359 return;
360
361 const bool succeeded = params.result() == PP_OK;
362 if (succeeded) {
363 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
364 if (!data.empty())
365 memcpy(read_buffer_, data.c_str(), data.size());
366 }
367 read_buffer_ = NULL;
368 bytes_to_read_ = -1;
369
370 read_callback_->Run(
371 succeeded ?
372 static_cast<int32_t>(data.size()) :
yzshen1 2013/08/16 20:40:42 four more spaces of indent, please.
ygorshenin1 2013/08/19 14:33:35 Done.
373 pp_utils::ConvertPPError(params.result(), private_api_));
374 }
375
376 void TCPSocketResourceBase::OnPluginMsgWriteReply(
377 const ResourceMessageReplyParams& params) {
378 if (!TrackedCallback::IsPending(write_callback_))
379 return;
380 RunCallback(write_callback_, params.result());
381 }
382
383 void TCPSocketResourceBase::OnPluginMsgSetOptionReply(
384 const ResourceMessageReplyParams& params) {
385 if (set_option_callbacks_.empty()) {
386 NOTREACHED();
387 return;
388 }
389 scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front();
390 set_option_callbacks_.pop();
391 if (TrackedCallback::IsPending(callback))
392 RunCallback(callback, params.result());
393 }
394
395 void TCPSocketResourceBase::RunCallback(scoped_refptr<TrackedCallback> callback,
396 int32_t pp_result) {
397 callback->Run(pp_utils::ConvertPPError(pp_result, private_api_));
398 }
399
372 } // namespace ppapi 400 } // namespace ppapi
401 } // namespace proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698