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 <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 |