OLD | NEW |
---|---|
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 "webkit/plugins/ppapi/ppb_websocket_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_websocket_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "googleurl/src/gurl.h" | 11 #include "googleurl/src/gurl.h" |
11 #include "net/base/net_util.h" | 12 #include "net/base/net_util.h" |
12 #include "ppapi/c/pp_completion_callback.h" | 13 #include "ppapi/c/pp_completion_callback.h" |
13 #include "ppapi/c/pp_errors.h" | 14 #include "ppapi/c/pp_errors.h" |
14 #include "ppapi/c/pp_var.h" | 15 #include "ppapi/c/pp_var.h" |
15 #include "ppapi/c/ppb_var.h" | 16 #include "ppapi/c/ppb_var.h" |
16 #include "ppapi/shared_impl/var.h" | 17 #include "ppapi/shared_impl/var.h" |
17 #include "ppapi/shared_impl/var_tracker.h" | 18 #include "ppapi/shared_impl/var_tracker.h" |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h" | 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h" |
(...skipping 12 matching lines...) Expand all Loading... | |
31 using ppapi::thunk::PPB_WebSocket_API; | 32 using ppapi::thunk::PPB_WebSocket_API; |
32 using ppapi::VarTracker; | 33 using ppapi::VarTracker; |
33 using WebKit::WebData; | 34 using WebKit::WebData; |
34 using WebKit::WebDocument; | 35 using WebKit::WebDocument; |
35 using WebKit::WebString; | 36 using WebKit::WebString; |
36 using WebKit::WebSocket; | 37 using WebKit::WebSocket; |
37 using WebKit::WebSocketClient; | 38 using WebKit::WebSocketClient; |
38 using WebKit::WebURL; | 39 using WebKit::WebURL; |
39 | 40 |
40 static const uint32_t kMaxReasonSizeInBytes = 123; | 41 static const uint32_t kMaxReasonSizeInBytes = 123; |
42 static const size_t kHybiBaseFramingOverhead = 2; | |
Yuta Kitamura
2011/11/30 13:46:20
I guess |static| is unnecessary; in C++, namespace
Takashi Toyoshima
2011/11/30 14:47:22
Done.
| |
43 static const size_t kHybiMaskingKeyLength = 4; | |
44 static const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; | |
45 static const size_t kMinimumPayloadSizeWithEightByteExtendedPayloadLength = | |
46 0x10000; | |
47 | |
48 static uint64_t SaturateAdd(uint64_t a, uint64_t b) { | |
Yuta Kitamura
2011/11/30 13:46:20
We prefer functions in unnamed namespace over stat
Takashi Toyoshima
2011/11/30 14:47:22
Done.
| |
49 if (kuint64max - a < b) | |
50 return kuint64max; | |
51 return a + b; | |
52 } | |
53 | |
54 static uint64_t GetFrameSize(uint64_t payload_size) { | |
55 if (!payload_size) | |
56 return 0; | |
57 | |
58 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; | |
59 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) | |
60 overhead += 8; | |
61 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) | |
62 overhead += 2; | |
63 return SaturateAdd(payload_size, overhead); | |
64 } | |
41 | 65 |
42 namespace webkit { | 66 namespace webkit { |
43 namespace ppapi { | 67 namespace ppapi { |
44 | 68 |
45 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) | 69 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) |
46 : Resource(instance), | 70 : Resource(instance), |
47 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), | 71 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), |
48 receive_callback_var_(NULL), | 72 receive_callback_var_(NULL), |
49 wait_for_receive_(false), | 73 wait_for_receive_(false), |
50 close_code_(0), | 74 close_code_(0), |
51 close_was_clean_(PP_FALSE) { | 75 close_was_clean_(PP_FALSE), |
76 buffered_amount_(0), | |
77 buffered_amount_after_close_(0) { | |
52 empty_string_ = new StringVar( | 78 empty_string_ = new StringVar( |
53 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); | 79 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); |
54 } | 80 } |
55 | 81 |
56 PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { | 82 PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { |
57 if (websocket_.get()) | 83 if (websocket_.get()) |
58 websocket_->disconnect(); | 84 websocket_->disconnect(); |
59 | 85 |
60 // Clean up received and unread messages | 86 // Clean up received and unread messages |
61 VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); | 87 VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 if (!websocket_.get()) | 264 if (!websocket_.get()) |
239 return PP_ERROR_FAILED; | 265 return PP_ERROR_FAILED; |
240 | 266 |
241 // Check state. | 267 // Check state. |
242 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || | 268 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || |
243 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 269 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
244 return PP_ERROR_BADARGUMENT; | 270 return PP_ERROR_BADARGUMENT; |
245 | 271 |
246 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || | 272 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || |
247 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { | 273 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { |
248 // TODO(toyoshim): Handle bufferedAmount here. | 274 // Handle buffered_amount_after_close_. |
275 uint64_t payload_size = 0; | |
276 if (message.type == PP_VARTYPE_STRING) { | |
277 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | |
278 if (message_string) | |
279 payload_size += message_string->value().length(); | |
280 } | |
281 // TODO(toyoshim): Support binary data. | |
282 | |
283 buffered_amount_after_close_ = | |
284 SaturateAdd(buffered_amount_after_close_, GetFrameSize(payload_size)); | |
285 | |
286 return PP_ERROR_FAILED; | |
249 } | 287 } |
250 | 288 |
251 if (message.type != PP_VARTYPE_STRING) { | 289 if (message.type != PP_VARTYPE_STRING) { |
252 // TODO(toyoshim): Support binary data. | 290 // TODO(toyoshim): Support binary data. |
253 return PP_ERROR_NOTSUPPORTED; | 291 return PP_ERROR_NOTSUPPORTED; |
254 } | 292 } |
255 | 293 |
256 // Convert message to WebString. | 294 // Convert message to WebString. |
257 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | 295 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); |
258 if (!message_string) | 296 if (!message_string) |
259 return PP_ERROR_BADARGUMENT; | 297 return PP_ERROR_BADARGUMENT; |
260 WebString web_message = WebString::fromUTF8(message_string->value()); | 298 WebString web_message = WebString::fromUTF8(message_string->value()); |
261 if (!websocket_->sendText(web_message)) | 299 if (!websocket_->sendText(web_message)) |
262 return PP_ERROR_BADARGUMENT; | 300 return PP_ERROR_BADARGUMENT; |
263 | 301 |
264 return PP_OK; | 302 return PP_OK; |
265 } | 303 } |
266 | 304 |
267 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { | 305 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { |
268 // TODO(toyoshim): Implement. | 306 return SaturateAdd(buffered_amount_, buffered_amount_after_close_); |
269 return 0; | |
270 } | 307 } |
271 | 308 |
272 uint16_t PPB_WebSocket_Impl::GetCloseCode() { | 309 uint16_t PPB_WebSocket_Impl::GetCloseCode() { |
273 return close_code_; | 310 return close_code_; |
274 } | 311 } |
275 | 312 |
276 PP_Var PPB_WebSocket_Impl::GetCloseReason() { | 313 PP_Var PPB_WebSocket_Impl::GetCloseReason() { |
277 if (!close_reason_) | 314 if (!close_reason_) |
278 return empty_string_->GetPPVar(); | 315 return empty_string_->GetPPVar(); |
279 return close_reason_->GetPPVar(); | 316 return close_reason_->GetPPVar(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { | 367 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
331 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; | 368 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
332 // TODO(toyoshim): Support to receive binary data. | 369 // TODO(toyoshim): Support to receive binary data. |
333 } | 370 } |
334 | 371 |
335 void PPB_WebSocket_Impl::didReceiveMessageError() { | 372 void PPB_WebSocket_Impl::didReceiveMessageError() { |
336 // TODO(toyoshim): Must implement. | 373 // TODO(toyoshim): Must implement. |
337 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; | 374 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; |
338 } | 375 } |
339 | 376 |
340 void PPB_WebSocket_Impl::didUpdateBufferedAmount(unsigned long bufferedAmount) { | 377 void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
341 // TODO(toyoshim): Must implement. | 378 unsigned long buffered_amount) { |
342 DLOG(INFO) << "didUpdateBufferedAmount is not implemented yet."; | 379 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
380 return; | |
381 buffered_amount_ = buffered_amount; | |
343 } | 382 } |
344 | 383 |
345 void PPB_WebSocket_Impl::didStartClosingHandshake() { | 384 void PPB_WebSocket_Impl::didStartClosingHandshake() { |
346 // TODO(toyoshim): Must implement. | 385 // TODO(toyoshim): Must implement. |
347 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; | 386 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; |
348 } | 387 } |
349 | 388 |
350 void PPB_WebSocket_Impl::didClose(unsigned long bufferedAmount, | 389 void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, |
351 ClosingHandshakeCompletionStatus status, | 390 ClosingHandshakeCompletionStatus status, |
352 unsigned short code, | 391 unsigned short code, |
353 const WebString& reason) { | 392 const WebString& reason) { |
354 // Store code and reason. | 393 // Store code and reason. |
355 close_code_ = code; | 394 close_code_ = code; |
356 std::string reason_string = reason.utf8(); | 395 std::string reason_string = reason.utf8(); |
357 close_reason_ = new StringVar( | 396 close_reason_ = new StringVar( |
358 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); | 397 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); |
359 | 398 |
360 // TODO(toyoshim): Set close_was_clean_. | 399 // TODO(toyoshim): Set close_was_clean_. |
361 | 400 |
362 // Handle state transition and invoking callback. | 401 // Handle state transition and invoking callback. |
363 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); | 402 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
364 PP_WebSocketReadyState_Dev state = state_; | 403 PP_WebSocketReadyState_Dev state = state_; |
365 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; | 404 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
366 | 405 |
406 // Update buffered_amount_. | |
407 buffered_amount_ = buffered_amount; | |
408 | |
367 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 409 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
368 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 410 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
369 | 411 |
370 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | 412 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
371 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); | 413 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
372 } | 414 } |
373 | 415 |
374 int32_t PPB_WebSocket_Impl::DoReceive() { | 416 int32_t PPB_WebSocket_Impl::DoReceive() { |
375 // TODO(toyoshim): Check state. | 417 // TODO(toyoshim): Check state. |
376 | 418 |
377 if (!receive_callback_var_) | 419 if (!receive_callback_var_) |
378 return PP_OK; | 420 return PP_OK; |
379 | 421 |
380 *receive_callback_var_ = received_messages_.front(); | 422 *receive_callback_var_ = received_messages_.front(); |
381 received_messages_.pop(); | 423 received_messages_.pop(); |
382 receive_callback_var_ = NULL; | 424 receive_callback_var_ = NULL; |
383 wait_for_receive_ = false; | 425 wait_for_receive_ = false; |
384 return PP_OK; | 426 return PP_OK; |
385 } | 427 } |
386 | 428 |
387 } // namespace ppapi | 429 } // namespace ppapi |
388 } // namespace webkit | 430 } // namespace webkit |
OLD | NEW |