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