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 |