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

Side by Side Diff: ppapi/shared_impl/tcp_socket_impl.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: Added PPAPI_IN_PROCESS TCP and UDP 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ppapi/shared_impl/tcp_socket_impl.h"
6
7 #include <string.h>
8
9 #include <algorithm>
10
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "ppapi/c/pp_errors.h"
14
15 namespace ppapi {
16
17 const int32_t TCPSocketImpl::kMaxReadSize = 1024 * 1024;
18 const int32_t TCPSocketImpl::kMaxWriteSize = 1024 * 1024;
19
20 TCPSocketImpl::TCPSocketImpl(PP_Instance instance, uint32 socket_id)
21 : Resource(instance) {
22 Init(socket_id);
23 }
24
25 TCPSocketImpl::TCPSocketImpl(const HostResource& resource, uint32 socket_id)
26 : Resource(resource) {
27 Init(socket_id);
28 }
29
30 TCPSocketImpl::~TCPSocketImpl() {
31 }
32
33 thunk::PPB_TCPSocket_Private_API*
34 TCPSocketImpl::AsPPB_TCPSocket_Private_API() {
35 return this;
36 }
37
38 int32_t TCPSocketImpl::Connect(const char* host,
39 uint16_t port,
40 PP_CompletionCallback callback) {
41 if (!host)
42 return PP_ERROR_BADARGUMENT;
43 if (!callback.func)
44 return PP_ERROR_BLOCKS_MAIN_THREAD;
45 if (connection_state_ != BEFORE_CONNECT)
46 return PP_ERROR_FAILED;
47 if (connect_callback_.func)
48 return PP_ERROR_INPROGRESS; // Can only have one pending request.
49
50 connect_callback_ = callback;
51 // Send the request, the browser will call us back via ConnectACK.
52 SendConnect(host, port);
53 return PP_OK_COMPLETIONPENDING;
54 }
55
56 int32_t TCPSocketImpl::ConnectWithNetAddress(
57 const PP_NetAddress_Private* addr,
58 PP_CompletionCallback callback) {
59 if (!addr)
60 return PP_ERROR_BADARGUMENT;
61 if (!callback.func)
62 return PP_ERROR_BLOCKS_MAIN_THREAD;
63 if (connection_state_ != BEFORE_CONNECT)
64 return PP_ERROR_FAILED;
65 if (connect_callback_.func)
66 return PP_ERROR_INPROGRESS; // Can only have one pending request.
67
68 connect_callback_ = callback;
69 // Send the request, the browser will call us back via ConnectACK.
70 SendConnectWithNetAddress(*addr);
71 return PP_OK_COMPLETIONPENDING;
72 }
73
74 PP_Bool TCPSocketImpl::GetLocalAddress(PP_NetAddress_Private* local_addr) {
75 if (!IsConnected() || !local_addr)
76 return PP_FALSE;
77
78 *local_addr = local_addr_;
79 return PP_TRUE;
80 }
81
82 PP_Bool TCPSocketImpl::GetRemoteAddress(PP_NetAddress_Private* remote_addr) {
83 if (!IsConnected() || !remote_addr)
84 return PP_FALSE;
85
86 *remote_addr = remote_addr_;
87 return PP_TRUE;
88 }
89
90 int32_t TCPSocketImpl::SSLHandshake(const char* server_name,
91 uint16_t server_port,
92 PP_CompletionCallback callback) {
93 if (!server_name)
94 return PP_ERROR_BADARGUMENT;
95 if (!callback.func)
96 return PP_ERROR_BLOCKS_MAIN_THREAD;
97
98 if (connection_state_ != CONNECTED)
99 return PP_ERROR_FAILED;
100 if (ssl_handshake_callback_.func || read_callback_.func ||
101 write_callback_.func)
102 return PP_ERROR_INPROGRESS;
103
104 ssl_handshake_callback_ = callback;
105
106 // Send the request, the browser will call us back via SSLHandshakeACK.
107 SendSSLHandshake(server_name, server_port);
108 return PP_OK_COMPLETIONPENDING;
109 }
110
111 int32_t TCPSocketImpl::Read(char* buffer,
112 int32_t bytes_to_read,
113 PP_CompletionCallback callback) {
114 if (!buffer || bytes_to_read <= 0)
115 return PP_ERROR_BADARGUMENT;
116 if (!callback.func)
117 return PP_ERROR_BLOCKS_MAIN_THREAD;
118
119 if (!IsConnected())
120 return PP_ERROR_FAILED;
121 if (read_callback_.func || ssl_handshake_callback_.func)
122 return PP_ERROR_INPROGRESS;
123 // TODO(dmichael): use some other strategy for determining if an
124 // operation is in progress
125 read_buffer_ = buffer;
126 bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize);
127 read_callback_ = callback;
128
129 // Send the request, the browser will call us back via ReadACK.
130 SendRead(bytes_to_read_);
131 return PP_OK_COMPLETIONPENDING;
132 }
133
134 int32_t TCPSocketImpl::Write(const char* buffer,
135 int32_t bytes_to_write,
136 PP_CompletionCallback callback) {
137 if (!buffer || bytes_to_write <= 0)
138 return PP_ERROR_BADARGUMENT;
139 if (!callback.func)
140 return PP_ERROR_BLOCKS_MAIN_THREAD;
141
142 if (!IsConnected())
143 return PP_ERROR_FAILED;
144 if (write_callback_.func || ssl_handshake_callback_.func)
145 return PP_ERROR_INPROGRESS;
146
147 if (bytes_to_write > kMaxWriteSize)
148 bytes_to_write = kMaxWriteSize;
149
150 write_callback_ = callback;
151
152 // Send the request, the browser will call us back via WriteACK.
153 SendWrite(std::string(buffer, bytes_to_write));
154 return PP_OK_COMPLETIONPENDING;
155 }
156
157 void TCPSocketImpl::Disconnect() {
158 if (connection_state_ == DISCONNECTED)
159 return;
160
161 connection_state_ = DISCONNECTED;
162
163 SendDisconnect();
164 socket_id_ = 0;
165
166 PostAbortAndClearIfNecessary(&connect_callback_);
167 PostAbortAndClearIfNecessary(&ssl_handshake_callback_);
168 PostAbortAndClearIfNecessary(&read_callback_);
169 PostAbortAndClearIfNecessary(&write_callback_);
170 read_buffer_ = NULL;
171 bytes_to_read_ = -1;
172 }
173
174 void TCPSocketImpl::OnConnectCompleted(
175 bool succeeded,
176 const PP_NetAddress_Private& local_addr,
177 const PP_NetAddress_Private& remote_addr) {
178 if (connection_state_ != BEFORE_CONNECT || !connect_callback_.func) {
179 NOTREACHED();
180 return;
181 }
182
183 if (succeeded) {
184 local_addr_ = local_addr;
185 remote_addr_ = remote_addr;
186 connection_state_ = CONNECTED;
187 }
188 PP_RunAndClearCompletionCallback(&connect_callback_,
189 succeeded ? PP_OK : PP_ERROR_FAILED);
190 }
191
192 void TCPSocketImpl::OnSSLHandshakeCompleted(bool succeeded) {
193 if (connection_state_ != CONNECTED || !ssl_handshake_callback_.func) {
194 NOTREACHED();
195 return;
196 }
197
198 if (succeeded) {
199 connection_state_ = SSL_CONNECTED;
200 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_OK);
201 } else {
202 PP_RunAndClearCompletionCallback(&ssl_handshake_callback_, PP_ERROR_FAILED);
203 Disconnect();
204 }
205 }
206
207 void TCPSocketImpl::OnReadCompleted(bool succeeded,
208 const std::string& data) {
209 if (!read_callback_.func || !read_buffer_) {
210 NOTREACHED();
211 return;
212 }
213
214 if (succeeded) {
215 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
216 if (!data.empty())
217 memcpy(read_buffer_, data.c_str(), data.size());
218 }
219 read_buffer_ = NULL;
220 bytes_to_read_ = -1;
221
222 PP_RunAndClearCompletionCallback(
223 &read_callback_,
224 succeeded ? static_cast<int32_t>(data.size()) :
225 static_cast<int32_t>(PP_ERROR_FAILED));
226 }
227
228 void TCPSocketImpl::OnWriteCompleted(bool succeeded,
229 int32_t bytes_written) {
230 if (!write_callback_.func || (succeeded && bytes_written < 0)) {
231 NOTREACHED();
232 return;
233 }
234
235 PP_RunAndClearCompletionCallback(
236 &write_callback_,
237 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
238 }
239
240 void TCPSocketImpl::Init(uint32 socket_id) {
241 DCHECK(socket_id != 0);
242 socket_id_ = socket_id;
243 connection_state_ = BEFORE_CONNECT;
244 connect_callback_ = PP_BlockUntilComplete();
245 ssl_handshake_callback_ = PP_BlockUntilComplete();
246 read_callback_ = PP_BlockUntilComplete();
247 write_callback_ = PP_BlockUntilComplete();
248 read_buffer_ = NULL;
249 bytes_to_read_ = -1;
250
251 local_addr_.size = 0;
252 memset(local_addr_.data, 0,
253 arraysize(local_addr_.data) * sizeof(*local_addr_.data));
254 remote_addr_.size = 0;
255 memset(remote_addr_.data, 0,
256 arraysize(remote_addr_.data) * sizeof(*remote_addr_.data));
257 }
258
259 bool TCPSocketImpl::IsConnected() const {
260 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED;
261 }
262
263 void TCPSocketImpl::PostAbortAndClearIfNecessary(
264 PP_CompletionCallback* callback) {
265 DCHECK(callback);
266
267 if (callback->func) {
268 PostAbort(*callback);
269 *callback = PP_BlockUntilComplete();
270 }
271 }
272
273 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698