Chromium Code Reviews| 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 <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "googleurl/src/gurl.h" | 12 #include "googleurl/src/gurl.h" |
| 13 #include "net/base/net_util.h" | 13 #include "net/base/net_util.h" |
| 14 #include "ppapi/c/dev/ppb_var_array_buffer_dev.h" | |
| 14 #include "ppapi/c/pp_completion_callback.h" | 15 #include "ppapi/c/pp_completion_callback.h" |
| 15 #include "ppapi/c/pp_errors.h" | 16 #include "ppapi/c/pp_errors.h" |
| 16 #include "ppapi/c/pp_var.h" | 17 #include "ppapi/c/pp_var.h" |
| 17 #include "ppapi/c/ppb_var.h" | 18 #include "ppapi/c/ppb_var.h" |
| 18 #include "ppapi/shared_impl/var.h" | 19 #include "ppapi/shared_impl/var.h" |
| 19 #include "ppapi/shared_impl/var_tracker.h" | 20 #include "ppapi/shared_impl/var_tracker.h" |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h" | 21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebData.h" |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" |
| 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" | 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" |
| 24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSocket.h" |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" |
| 27 #include "webkit/plugins/ppapi/host_globals.h" | 28 #include "webkit/plugins/ppapi/host_globals.h" |
| 28 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 29 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 29 #include "webkit/plugins/ppapi/resource_helper.h" | 30 #include "webkit/plugins/ppapi/resource_helper.h" |
| 30 | 31 |
| 32 using ppapi::ArrayBufferVar; | |
| 31 using ppapi::PpapiGlobals; | 33 using ppapi::PpapiGlobals; |
| 32 using ppapi::StringVar; | 34 using ppapi::StringVar; |
| 33 using ppapi::thunk::PPB_WebSocket_API; | 35 using ppapi::thunk::PPB_WebSocket_API; |
| 34 using ppapi::VarTracker; | 36 using ppapi::VarTracker; |
| 35 using WebKit::WebData; | 37 using WebKit::WebData; |
| 36 using WebKit::WebDocument; | 38 using WebKit::WebDocument; |
| 37 using WebKit::WebString; | 39 using WebKit::WebString; |
| 38 using WebKit::WebSocket; | 40 using WebKit::WebSocket; |
| 39 using WebKit::WebSocketClient; | 41 using WebKit::WebSocketClient; |
| 40 using WebKit::WebURL; | 42 using WebKit::WebURL; |
| 41 | 43 |
| 42 const uint32_t kMaxReasonSizeInBytes = 123; | 44 const uint32_t kMaxReasonSizeInBytes = 123; |
| 43 const size_t kHybiBaseFramingOverhead = 2; | 45 const size_t kHybiBaseFramingOverhead = 2; |
| 44 const size_t kHybiMaskingKeyLength = 4; | 46 const size_t kHybiMaskingKeyLength = 4; |
| 45 const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; | 47 const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; |
| 46 const size_t kMinimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000; | 48 const size_t kMinimumPayloadSizeWithEightByteExtendedPayloadLength = 0x10000; |
| 47 | 49 |
| 48 namespace { | 50 namespace { |
| 49 | 51 |
| 50 uint64_t SaturateAdd(uint64_t a, uint64_t b) { | 52 uint64_t SaturateAdd(uint64_t a, uint64_t b) { |
| 51 if (kuint64max - a < b) | 53 if (kuint64max - a < b) |
| 52 return kuint64max; | 54 return kuint64max; |
| 53 return a + b; | 55 return a + b; |
| 54 } | 56 } |
| 55 | 57 |
| 56 uint64_t GetFrameSize(uint64_t payload_size) { | 58 uint64_t GetFrameSize(uint64_t payload_size) { |
| 57 if (!payload_size) | |
| 58 return 0; | |
| 59 | |
| 60 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; | 59 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; |
| 61 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) | 60 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) |
| 62 overhead += 8; | 61 overhead += 8; |
| 63 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) | 62 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) |
| 64 overhead += 2; | 63 overhead += 2; |
| 65 return SaturateAdd(payload_size, overhead); | 64 return SaturateAdd(payload_size, overhead); |
| 66 } | 65 } |
| 67 | 66 |
| 68 bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) { | 67 bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) { |
| 69 return state == PP_WEBSOCKETREADYSTATE_OPEN_DEV || | 68 return state == PP_WEBSOCKETREADYSTATE_OPEN_DEV || |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 return PP_ERROR_BADARGUMENT; | 312 return PP_ERROR_BADARGUMENT; |
| 314 | 313 |
| 315 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || | 314 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || |
| 316 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { | 315 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { |
| 317 // Handle buffered_amount_after_close_. | 316 // Handle buffered_amount_after_close_. |
| 318 uint64_t payload_size = 0; | 317 uint64_t payload_size = 0; |
| 319 if (message.type == PP_VARTYPE_STRING) { | 318 if (message.type == PP_VARTYPE_STRING) { |
| 320 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | 319 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); |
| 321 if (message_string) | 320 if (message_string) |
| 322 payload_size += message_string->value().length(); | 321 payload_size += message_string->value().length(); |
| 322 } else if (message.type == PP_VARTYPE_ARRAY_BUFFER) { | |
| 323 scoped_refptr<ArrayBufferVar> message_array_buffer = | |
| 324 ArrayBufferVar::FromPPVar(message); | |
| 325 if (message_array_buffer) | |
| 326 payload_size += message_array_buffer->ByteLength(); | |
| 327 } else { | |
| 328 // TODO(toyoshim): Support Blob. | |
| 329 return PP_ERROR_NOTSUPPORTED; | |
| 323 } | 330 } |
| 324 // TODO(toyoshim): Support binary data. | |
| 325 | 331 |
| 326 buffered_amount_after_close_ = | 332 buffered_amount_after_close_ = |
| 327 SaturateAdd(buffered_amount_after_close_, GetFrameSize(payload_size)); | 333 SaturateAdd(buffered_amount_after_close_, GetFrameSize(payload_size)); |
| 328 | 334 |
| 329 return PP_ERROR_FAILED; | 335 return PP_ERROR_FAILED; |
| 330 } | 336 } |
| 331 | 337 |
| 332 if (message.type != PP_VARTYPE_STRING) { | 338 // Send the message. |
| 333 // TODO(toyoshim): Support binary data. | 339 if (message.type == PP_VARTYPE_STRING) { |
| 340 // Convert message to WebString. | |
| 341 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | |
| 342 if (!message_string) | |
| 343 return PP_ERROR_BADARGUMENT; | |
| 344 WebString web_message = WebString::fromUTF8(message_string->value()); | |
| 345 if (!websocket_->sendText(web_message)) | |
| 346 return PP_ERROR_BADARGUMENT; | |
| 347 } else if (message.type == PP_VARTYPE_ARRAY_BUFFER) { | |
| 348 // Convert message to WebData. | |
| 349 // TODO(toyoshim): Must add a WebKit interface which handles WebArrayBuffer | |
| 350 // directory. | |
|
dmichael (off chromium)
2011/12/20 17:11:06
directory->directly?
Takashi Toyoshima
2011/12/21 07:45:57
Done.
| |
| 351 scoped_refptr<ArrayBufferVar> message_array_buffer = | |
| 352 ArrayBufferVar::FromPPVar(message); | |
| 353 if (!message_array_buffer) | |
| 354 return PP_ERROR_BADARGUMENT; | |
| 355 WebData web_message = WebData( | |
| 356 static_cast<const char*>(message_array_buffer->Map()), | |
| 357 static_cast<size_t>(message_array_buffer->ByteLength())); | |
| 358 if (!websocket_->sendBinary(web_message)) | |
| 359 return PP_ERROR_BADARGUMENT; | |
| 360 } else { | |
| 361 // TODO(toyoshim): Support Blob. | |
| 334 return PP_ERROR_NOTSUPPORTED; | 362 return PP_ERROR_NOTSUPPORTED; |
| 335 } | 363 } |
| 336 | 364 |
| 337 // Convert message to WebString. | |
| 338 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | |
| 339 if (!message_string) | |
| 340 return PP_ERROR_BADARGUMENT; | |
| 341 WebString web_message = WebString::fromUTF8(message_string->value()); | |
| 342 if (!websocket_->sendText(web_message)) | |
| 343 return PP_ERROR_BADARGUMENT; | |
| 344 | |
| 345 return PP_OK; | 365 return PP_OK; |
| 346 } | 366 } |
| 347 | 367 |
| 348 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { | 368 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { |
| 349 return SaturateAdd(buffered_amount_, buffered_amount_after_close_); | 369 return SaturateAdd(buffered_amount_, buffered_amount_after_close_); |
| 350 } | 370 } |
| 351 | 371 |
| 352 uint16_t PPB_WebSocket_Impl::GetCloseCode() { | 372 uint16_t PPB_WebSocket_Impl::GetCloseCode() { |
| 353 return close_code_; | 373 return close_code_; |
| 354 } | 374 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 return; | 430 return; |
| 411 | 431 |
| 412 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); | 432 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); |
| 413 } | 433 } |
| 414 | 434 |
| 415 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { | 435 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
| 416 // Dispose packets after receiving an error or in invalid state. | 436 // Dispose packets after receiving an error or in invalid state. |
| 417 if (error_was_received_ || !InValidStateToReceive(state_)) | 437 if (error_was_received_ || !InValidStateToReceive(state_)) |
| 418 return; | 438 return; |
| 419 | 439 |
| 420 // TODO(toyoshim): Support to receive binary data. | 440 // Append received data to queue. |
| 421 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; | 441 PP_Var var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
| 442 binaryData.size()); | |
| 443 scoped_refptr<ArrayBufferVar> arraybuffer = ArrayBufferVar::FromPPVar(var); | |
| 444 void* data = arraybuffer->Map(); | |
| 445 memcpy(data, binaryData.data(), binaryData.size()); | |
| 446 received_messages_.push(var); | |
| 447 | |
| 448 if (!wait_for_receive_) | |
| 449 return; | |
| 450 | |
| 451 PP_RunAndClearCompletionCallback(&receive_callback_, DoReceive()); | |
| 422 } | 452 } |
| 423 | 453 |
| 424 void PPB_WebSocket_Impl::didReceiveMessageError() { | 454 void PPB_WebSocket_Impl::didReceiveMessageError() { |
| 425 // Ignore error notification in invalid state. | 455 // Ignore error notification in invalid state. |
| 426 if (!InValidStateToReceive(state_)) | 456 if (!InValidStateToReceive(state_)) |
| 427 return; | 457 return; |
| 428 | 458 |
| 429 // Records the error, then stops receiving any frames after this error. | 459 // Records the error, then stops receiving any frames after this error. |
| 430 // The error will be notified after all queued messages are read via | 460 // The error will be notified after all queued messages are read via |
| 431 // ReceiveMessage(). | 461 // ReceiveMessage(). |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 | 528 |
| 499 *receive_callback_var_ = received_messages_.front(); | 529 *receive_callback_var_ = received_messages_.front(); |
| 500 received_messages_.pop(); | 530 received_messages_.pop(); |
| 501 receive_callback_var_ = NULL; | 531 receive_callback_var_ = NULL; |
| 502 wait_for_receive_ = false; | 532 wait_for_receive_ = false; |
| 503 return PP_OK; | 533 return PP_OK; |
| 504 } | 534 } |
| 505 | 535 |
| 506 } // namespace ppapi | 536 } // namespace ppapi |
| 507 } // namespace webkit | 537 } // namespace webkit |
| OLD | NEW |