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; | |
43 static const size_t kHybiMaskingKeyLength = 4; | |
44 static const size_t kMinimumPayloadSizeWithTwoByteExtendedPayloadLength = 126; | |
45 static const size_t kMinimumPayloadSizeWithEightByteExtendedPayloadLength = | |
46 0x10000; | |
41 | 47 |
42 namespace webkit { | 48 namespace webkit { |
43 namespace ppapi { | 49 namespace ppapi { |
44 | 50 |
45 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) | 51 PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) |
46 : Resource(instance), | 52 : Resource(instance), |
47 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), | 53 state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), |
48 receive_callback_var_(NULL), | 54 receive_callback_var_(NULL), |
49 wait_for_receive_(false), | 55 wait_for_receive_(false), |
50 close_code_(0), | 56 close_code_(0), |
51 close_was_clean_(PP_FALSE) { | 57 close_was_clean_(PP_FALSE), |
58 buffered_amount_(0), | |
59 buffered_amount_after_close_(0) { | |
52 empty_string_ = new StringVar( | 60 empty_string_ = new StringVar( |
53 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); | 61 PpapiGlobals::Get()->GetModuleForInstance(instance), "", 0); |
54 } | 62 } |
55 | 63 |
56 PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { | 64 PPB_WebSocket_Impl::~PPB_WebSocket_Impl() { |
57 if (websocket_.get()) | 65 if (websocket_.get()) |
58 websocket_->disconnect(); | 66 websocket_->disconnect(); |
59 | 67 |
60 // Clean up received and unread messages | 68 // Clean up received and unread messages |
61 VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); | 69 VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 if (!websocket_.get()) | 246 if (!websocket_.get()) |
239 return PP_ERROR_FAILED; | 247 return PP_ERROR_FAILED; |
240 | 248 |
241 // Check state. | 249 // Check state. |
242 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || | 250 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || |
243 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 251 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
244 return PP_ERROR_BADARGUMENT; | 252 return PP_ERROR_BADARGUMENT; |
245 | 253 |
246 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || | 254 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || |
247 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { | 255 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) { |
248 // TODO(toyoshim): Handle bufferedAmount here. | 256 // Handle buffered_amount_after_close_. |
257 uint64_t payload_size = 0; | |
258 if (message.type == PP_VARTYPE_STRING) { | |
259 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | |
260 if (message_string) | |
261 payload_size += message_string->value().length(); | |
Yuta Kitamura
2011/11/30 11:40:48
Is this byte length in UTF-8?
Takashi Toyoshima
2011/11/30 12:29:12
Yes.
StringVar::value() returns std::string& direc
| |
262 } | |
263 // TODO(toyoshim): Support binary data. | |
264 | |
265 buffered_amount_after_close_ = | |
266 SaturateAdd(buffered_amount_after_close_, GetFrameSize(payload_size)); | |
267 | |
268 return PP_ERROR_FAILED; | |
249 } | 269 } |
250 | 270 |
251 if (message.type != PP_VARTYPE_STRING) { | 271 if (message.type != PP_VARTYPE_STRING) { |
252 // TODO(toyoshim): Support binary data. | 272 // TODO(toyoshim): Support binary data. |
253 return PP_ERROR_NOTSUPPORTED; | 273 return PP_ERROR_NOTSUPPORTED; |
254 } | 274 } |
255 | 275 |
256 // Convert message to WebString. | 276 // Convert message to WebString. |
257 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); | 277 scoped_refptr<StringVar> message_string = StringVar::FromPPVar(message); |
258 if (!message_string) | 278 if (!message_string) |
259 return PP_ERROR_BADARGUMENT; | 279 return PP_ERROR_BADARGUMENT; |
260 WebString web_message = WebString::fromUTF8(message_string->value()); | 280 WebString web_message = WebString::fromUTF8(message_string->value()); |
261 if (!websocket_->sendText(web_message)) | 281 if (!websocket_->sendText(web_message)) |
262 return PP_ERROR_BADARGUMENT; | 282 return PP_ERROR_BADARGUMENT; |
263 | 283 |
264 return PP_OK; | 284 return PP_OK; |
265 } | 285 } |
266 | 286 |
267 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { | 287 uint64_t PPB_WebSocket_Impl::GetBufferedAmount() { |
268 // TODO(toyoshim): Implement. | 288 return SaturateAdd(buffered_amount_, buffered_amount_after_close_); |
269 return 0; | |
270 } | 289 } |
271 | 290 |
272 uint16_t PPB_WebSocket_Impl::GetCloseCode() { | 291 uint16_t PPB_WebSocket_Impl::GetCloseCode() { |
273 return close_code_; | 292 return close_code_; |
274 } | 293 } |
275 | 294 |
276 PP_Var PPB_WebSocket_Impl::GetCloseReason() { | 295 PP_Var PPB_WebSocket_Impl::GetCloseReason() { |
277 if (!close_reason_) | 296 if (!close_reason_) |
278 return empty_string_->GetPPVar(); | 297 return empty_string_->GetPPVar(); |
279 return close_reason_->GetPPVar(); | 298 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) { | 349 void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
331 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; | 350 DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
332 // TODO(toyoshim): Support to receive binary data. | 351 // TODO(toyoshim): Support to receive binary data. |
333 } | 352 } |
334 | 353 |
335 void PPB_WebSocket_Impl::didReceiveMessageError() { | 354 void PPB_WebSocket_Impl::didReceiveMessageError() { |
336 // TODO(toyoshim): Must implement. | 355 // TODO(toyoshim): Must implement. |
337 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; | 356 DLOG(INFO) << "didReceiveMessageError is not implemented yet."; |
338 } | 357 } |
339 | 358 |
340 void PPB_WebSocket_Impl::didUpdateBufferedAmount(unsigned long bufferedAmount) { | 359 void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
341 // TODO(toyoshim): Must implement. | 360 unsigned long buffered_amount) { |
342 DLOG(INFO) << "didUpdateBufferedAmount is not implemented yet."; | 361 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
362 return; | |
363 buffered_amount_ = buffered_amount; | |
343 } | 364 } |
344 | 365 |
345 void PPB_WebSocket_Impl::didStartClosingHandshake() { | 366 void PPB_WebSocket_Impl::didStartClosingHandshake() { |
346 // TODO(toyoshim): Must implement. | 367 // TODO(toyoshim): Must implement. |
347 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; | 368 DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; |
348 } | 369 } |
349 | 370 |
350 void PPB_WebSocket_Impl::didClose(unsigned long bufferedAmount, | 371 void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, |
351 ClosingHandshakeCompletionStatus status, | 372 ClosingHandshakeCompletionStatus status, |
352 unsigned short code, | 373 unsigned short code, |
353 const WebString& reason) { | 374 const WebString& reason) { |
354 // Store code and reason. | 375 // Store code and reason. |
355 close_code_ = code; | 376 close_code_ = code; |
356 std::string reason_string = reason.utf8(); | 377 std::string reason_string = reason.utf8(); |
357 close_reason_ = new StringVar( | 378 close_reason_ = new StringVar( |
358 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); | 379 PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); |
359 | 380 |
360 // TODO(toyoshim): Set close_was_clean_. | 381 // TODO(toyoshim): Set close_was_clean_. |
361 | 382 |
362 // Handle state transition and invoking callback. | 383 // Handle state transition and invoking callback. |
363 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); | 384 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
364 PP_WebSocketReadyState_Dev state = state_; | 385 PP_WebSocketReadyState_Dev state = state_; |
365 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; | 386 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
366 | 387 |
388 // Update buffered_amount_. | |
389 buffered_amount_ = buffered_amount; | |
390 | |
367 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 391 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
368 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 392 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
369 | 393 |
370 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | 394 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
371 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); | 395 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
372 } | 396 } |
373 | 397 |
374 int32_t PPB_WebSocket_Impl::DoReceive() { | 398 int32_t PPB_WebSocket_Impl::DoReceive() { |
375 // TODO(toyoshim): Check state. | 399 // TODO(toyoshim): Check state. |
376 | 400 |
377 if (!receive_callback_var_) | 401 if (!receive_callback_var_) |
378 return PP_OK; | 402 return PP_OK; |
379 | 403 |
380 *receive_callback_var_ = received_messages_.front(); | 404 *receive_callback_var_ = received_messages_.front(); |
381 received_messages_.pop(); | 405 received_messages_.pop(); |
382 receive_callback_var_ = NULL; | 406 receive_callback_var_ = NULL; |
383 wait_for_receive_ = false; | 407 wait_for_receive_ = false; |
384 return PP_OK; | 408 return PP_OK; |
385 } | 409 } |
386 | 410 |
411 uint64_t PPB_WebSocket_Impl::GetFrameSize(uint64_t payload_size) { | |
Yuta Kitamura
2011/11/30 11:40:48
See comments below.
| |
412 if (!payload_size) | |
413 return 0; | |
414 | |
415 uint64_t overhead = kHybiBaseFramingOverhead + kHybiMaskingKeyLength; | |
416 if (payload_size > kMinimumPayloadSizeWithEightByteExtendedPayloadLength) | |
417 overhead += 8; | |
418 else if (payload_size > kMinimumPayloadSizeWithTwoByteExtendedPayloadLength) | |
419 overhead += 2; | |
420 return SaturateAdd(payload_size, overhead); | |
421 } | |
422 | |
423 uint64_t PPB_WebSocket_Impl::SaturateAdd(uint64_t a, uint64_t b) { | |
Yuta Kitamura
2011/11/30 11:40:48
I prefer this function to belong unnamed namespace
Takashi Toyoshima
2011/11/30 12:29:12
OK.
I move them to top of this file as static func
| |
424 if (kuint64max - a < b) | |
425 return kuint64max; | |
426 return a + b; | |
427 } | |
428 | |
387 } // namespace ppapi | 429 } // namespace ppapi |
388 } // namespace webkit | 430 } // namespace webkit |
OLD | NEW |