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/basictypes.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 return 0; | 57 return 0; |
58 | 58 |
59 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; | 59 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; |
60 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) | 60 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) |
61 overhead += 8; | 61 overhead += 8; |
62 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) | 62 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) |
63 overhead += 2; | 63 overhead += 2; |
64 return SaturateAdd(payload_size, overhead); | 64 return SaturateAdd(payload_size, overhead); |
65 } | 65 } |
66 | 66 |
67 bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) { | |
68 if (state != PP_WEBSOCKETREADYSTATE_OPEN_DEV && | |
69 state != PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | |
70 return false; | |
71 return true; | |
dmichael (off chromium)
2011/12/02 16:28:09
suggestion/nit: could also have just been:
return
Takashi Toyoshima
2011/12/02 17:15:42
Sounds good.
Fixed.
| |
72 } | |
73 | |
67 } // namespace | 74 } // namespace |
68 | 75 |
69 namespace webkit { | 76 namespace webkit { |
70 namespace ppapi { | 77 namespace ppapi { |
71 | 78 |
72 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) | 79 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) |
73 : Resource(instance), | 80 : Resource(instance), |
74 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), | 81 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), |
82 error_was_received_(false), | |
75 receive_callback_var_(NULL), | 83 receive_callback_var_(NULL), |
76 wait_for_receive_(false), | 84 wait_for_receive_(false), |
77 close_code_(0), | 85 close_code_(0), |
78 close_was_clean_(PP_FALSE), | 86 close_was_clean_(PP_FALSE), |
79 buffered_amount_(0), | 87 buffered_amount_(0), |
80 buffered_amount_after_close_(0) { | 88 buffered_amount_after_close_(0) { |
81 empty_string_ = new StringVar( | 89 empty_string_ = new StringVar( |
82 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); | 90 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); |
83 } | 91 } |
84 | 92 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
242 return PP_OK_COMPLETIONPENDING; | 250 return PP_OK_COMPLETIONPENDING; |
243 } | 251 } |
244 | 252 |
245 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, | 253 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, |
246 PP_CompletionCallback callback) { | 254 PP_CompletionCallback callback) { |
247 // Check state. | 255 // Check state. |
248 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || | 256 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || |
249 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 257 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
250 return PP_ERROR_BADARGUMENT; | 258 return PP_ERROR_BADARGUMENT; |
251 | 259 |
260 // Validate |callback| (Doesn't support blocking callback) | |
261 if (!callback.func) | |
262 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
263 | |
252 // Just return received message if any received message is queued. | 264 // Just return received message if any received message is queued. |
253 if (!received_messages_.empty()) | 265 if (!received_messages_.empty()) |
254 return DoReceive(); | 266 return DoReceive(); |
255 | 267 |
268 // Returns PP_ERROR_FAILED after an error is received and received messages | |
269 // is exhausted. | |
270 if (error_was_received_) | |
271 return PP_ERROR_FAILED; | |
272 | |
256 // Or retain |message| as buffer to store and install |callback|. | 273 // Or retain |message| as buffer to store and install |callback|. |
257 wait_for_receive_ = true; | 274 wait_for_receive_ = true; |
258 receive_callback_var_ = message; | 275 receive_callback_var_ = message; |
259 receive_callback_ = callback; | 276 receive_callback_ = callback; |
260 | 277 |
261 return PP_OK_COMPLETIONPENDING; | 278 return PP_OK_COMPLETIONPENDING; |
262 } | 279 } |
263 | 280 |
264 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { | 281 int32_t PPB_WebSocket_Impl::SendMessage(PP_Var message) { |
265 // Check mandatory interfaces. | 282 // Check mandatory interfaces. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 return url_->GetPPVar(); | 367 return url_->GetPPVar(); |
351 } | 368 } |
352 | 369 |
353 void PPB_WebSocket_Impl::didConnect() { | 370 void PPB_WebSocket_Impl::didConnect() { |
354 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); | 371 DCHECK_EQ(PP_WEBSOCKETREADYSTATE_CONNECTING_DEV, state_); |
355 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; | 372 state_ = PP_WEBSOCKETREADYSTATE_OPEN_DEV; |
356 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 373 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
357 } | 374 } |
358 | 375 |
359 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { | 376 void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { |
377 // Dispose packets after receiving an error or in invalid state. | |
378 if (error_was_received_ || !InValidStateToReceive(state_)) | |
379 return; | |
380 | |
360 // Append received data to queue. | 381 // Append received data to queue. |
361 std::string string = message.utf8(); | 382 std::string string = message.utf8(); |
362 PP_Var var = StringVar::StringToPPVar( | 383 PP_Var var = StringVar::StringToPPVar( |
363 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string); | 384 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), string); |
364 received_messages_.push(var); | 385 received_messages_.push(var); |
365 | 386 |
366 if (!wait_for_receive_) | 387 if (!wait_for_receive_) |
367 return; | 388 return; |
368 | 389 |
369 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); | 390 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); |
370 } | 391 } |
371 | 392 |
372 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { | 393 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
394 // Dispose packets after receiving an error or in invalid state. | |
395 if (error_was_received_ || !InValidStateToReceive(state_)) | |
396 return; | |
397 | |
398 // TODO(toyoshim): Support to receive binary data. | |
373 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; | 399 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
374 // TODO(toyoshim): Support to receive binary data. | |
375 } | 400 } |
376 | 401 |
377 void PPB_WebSocket_Impl::didReceiveMessageError() { | 402 void PPB_WebSocket_Impl::didReceiveMessageError() { |
378 // TODO(toyoshim): Must implement. | 403 // Ignore error notification in invalid state. |
379 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; | 404 if (!InValidStateToReceive(state_)) |
405 return; | |
406 | |
407 // Records the error, then stops receiving any frames after this error. | |
408 // The error will be notified after all queued messages are read via | |
409 // ReceiveMessage(). | |
410 error_was_received_ = true; | |
411 if (!wait_for_receive_) | |
412 return; | |
413 | |
414 // But, if no messages is queued and ReceiveMessage() is now on going. | |
dmichael (off chromium)
2011/12/02 16:28:09
nit: is -> are
Takashi Toyoshima
2011/12/02 17:15:42
Done.
| |
415 // We must invoke the callback with error code here. | |
416 wait_for_receive_ = false; | |
417 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_FAILED); | |
380 } | 418 } |
381 | 419 |
382 void PPB_WebSocket_Impl::didUpdateBufferedAmount( | 420 void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
383 unsigned long buffered_amount) { | 421 unsigned long buffered_amount) { |
384 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) | 422 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
385 return; | 423 return; |
386 buffered_amount_ = buffered_amount; | 424 buffered_amount_ = buffered_amount; |
387 } | 425 } |
388 | 426 |
389 void PPB_WebSocket_Impl::didStartClosingHandshake() { | 427 void PPB_WebSocket_Impl::didStartClosingHandshake() { |
390 // TODO(toyoshim): Must implement. | 428 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; |
391 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; | |
392 } | 429 } |
393 | 430 |
394 void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, | 431 void PPB_WebSocket_Impl::didClose(unsigned long unhandled_buffered_amount, |
395 ClosingHandshakeCompletionStatus status, | 432 ClosingHandshakeCompletionStatus status, |
396 unsigned short code, | 433 unsigned short code, |
397 const WebString& reason) { | 434 const WebString& reason) { |
398 // Store code and reason. | 435 // Store code and reason. |
399 close_code_ = code; | 436 close_code_ = code; |
400 std::string reason_string = reason.utf8(); | 437 std::string reason_string = reason.utf8(); |
401 close_reason_ = new StringVar( | 438 close_reason_ = new StringVar( |
402 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); | 439 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); |
403 | 440 |
404 // TODO(toyoshim): Set close_was_clean_. | 441 // Set close_was_clean_. |
442 bool was_clean = | |
443 state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV && | |
444 !unhandled_buffered_amount && | |
445 status == WebSocketClient::ClosingHandshakeComplete; | |
446 close_was_clean_ = was_clean ? PP_TRUE : PP_FALSE; | |
447 | |
448 // Update buffered_amount_. | |
449 buffered_amount_ = unhandled_buffered_amount; | |
405 | 450 |
406 // Handle state transition and invoking callback. | 451 // Handle state transition and invoking callback. |
407 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); | 452 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
408 PP_WebSocketReadyState_Dev state = state_; | 453 PP_WebSocketReadyState_Dev state = state_; |
409 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; | 454 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
410 | 455 |
411 // Update buffered_amount_. | |
412 buffered_amount_ = buffered_amount; | |
413 | |
414 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 456 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
415 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 457 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
416 | 458 |
417 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | 459 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
418 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); | 460 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
461 | |
462 // Disconnect. | |
463 if (websocket_.get()) | |
464 websocket_->disconnect(); | |
419 } | 465 } |
420 | 466 |
421 int32_t PPB_WebSocket_Impl::DoReceive() { | 467 int32_t PPB_WebSocket_Impl::DoReceive() { |
422 // TODO(toyoshim): Check state. | |
423 | |
424 if (!receive_callback_var_) | 468 if (!receive_callback_var_) |
425 return PP_OK; | 469 return PP_OK; |
426 | 470 |
427 *receive_callback_var_ = received_messages_.front(); | 471 *receive_callback_var_ = received_messages_.front(); |
428 received_messages_.pop(); | 472 received_messages_.pop(); |
429 receive_callback_var_ = NULL; | 473 receive_callback_var_ = NULL; |
430 wait_for_receive_ = false; | 474 wait_for_receive_ = false; |
431 return PP_OK; | 475 return PP_OK; |
432 } | 476 } |
433 | 477 |
434 } // namespace ppapi | 478 } // namespace ppapi |
435 } // namespace webkit | 479 } // namespace webkit |
OLD | NEW |