| 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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 PP_CompletionCallback callback) { | 205 PP_CompletionCallback callback) { |
| 206 // Check mandarory interfaces. | 206 // Check mandarory interfaces. |
| 207 if (!websocket_.get()) | 207 if (!websocket_.get()) |
| 208 return PP_ERROR_FAILED; | 208 return PP_ERROR_FAILED; |
| 209 | 209 |
| 210 // Validate |code|. | 210 // Validate |code|. |
| 211 if (code != WebSocket::CloseEventCodeNotSpecified) { | 211 if (code != WebSocket::CloseEventCodeNotSpecified) { |
| 212 if (!(code == WebSocket::CloseEventCodeNormalClosure || | 212 if (!(code == WebSocket::CloseEventCodeNormalClosure || |
| 213 (WebSocket::CloseEventCodeMinimumUserDefined <= code && | 213 (WebSocket::CloseEventCodeMinimumUserDefined <= code && |
| 214 code <= WebSocket::CloseEventCodeMaximumUserDefined))) | 214 code <= WebSocket::CloseEventCodeMaximumUserDefined))) |
| 215 // RFC 6455 limits applications to use reserved connection close code in |
| 216 // section 7.4.2.. The WebSocket API (http://www.w3.org/TR/websockets/) |
| 217 // defines this out of range error as InvalidAccessError in JavaScript. |
| 215 return PP_ERROR_NOACCESS; | 218 return PP_ERROR_NOACCESS; |
| 216 } | 219 } |
| 217 | 220 |
| 218 // Validate |reason|. | 221 // Validate |reason|. |
| 219 // TODO(toyoshim): Returns PP_ERROR_BADARGUMENT if |reason| contains any | 222 // TODO(toyoshim): Returns PP_ERROR_BADARGUMENT if |reason| contains any |
| 220 // surrogates. | 223 // surrogates. |
| 221 scoped_refptr<StringVar> reason_string = StringVar::FromPPVar(reason); | 224 scoped_refptr<StringVar> reason_string = StringVar::FromPPVar(reason); |
| 222 if (!reason_string || reason_string->value().size() > kMaxReasonSizeInBytes) | 225 if (!reason_string || reason_string->value().size() > kMaxReasonSizeInBytes) |
| 223 return PP_ERROR_BADARGUMENT; | 226 return PP_ERROR_BADARGUMENT; |
| 224 | 227 |
| 225 // Check state. | 228 // Check state. |
| 226 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || | 229 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV || |
| 227 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) | 230 state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
| 228 return PP_ERROR_INPROGRESS; | 231 return PP_ERROR_INPROGRESS; |
| 229 | 232 |
| 230 // Validate |callback| (Doesn't support blocking callback) | 233 // Validate |callback| (Doesn't support blocking callback) |
| 231 if (!callback.func) | 234 if (!callback.func) |
| 232 return PP_ERROR_BLOCKS_MAIN_THREAD; | 235 return PP_ERROR_BLOCKS_MAIN_THREAD; |
| 233 | 236 |
| 234 // Install |callback|. | 237 // Install |callback|. |
| 235 close_callback_ = callback; | 238 close_callback_ = callback; |
| 236 | 239 |
| 240 // Abort ongoing connect. |
| 237 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) { | 241 if (state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) { |
| 238 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; | 242 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; |
| 239 PP_RunAndClearCompletionCallback(&connect_callback_, PP_ERROR_ABORTED); | 243 PP_RunAndClearCompletionCallback(&connect_callback_, PP_ERROR_ABORTED); |
| 240 websocket_->fail( | 244 websocket_->fail( |
| 241 "WebSocket was closed before the connection was established."); | 245 "WebSocket was closed before the connection was established."); |
| 242 return PP_OK_COMPLETIONPENDING; | 246 return PP_OK_COMPLETIONPENDING; |
| 243 } | 247 } |
| 244 | 248 |
| 249 // Abort ongoing receive. |
| 250 if (wait_for_receive_) { |
| 251 wait_for_receive_ = false; |
| 252 receive_callback_var_ = NULL; |
| 253 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_ABORTED); |
| 254 } |
| 255 |
| 245 // Close connection. | 256 // Close connection. |
| 246 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; | 257 state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; |
| 247 WebString web_reason = WebString::fromUTF8(reason_string->value()); | 258 WebString web_reason = WebString::fromUTF8(reason_string->value()); |
| 248 websocket_->close(code, web_reason); | 259 websocket_->close(code, web_reason); |
| 249 | 260 |
| 250 return PP_OK_COMPLETIONPENDING; | 261 return PP_OK_COMPLETIONPENDING; |
| 251 } | 262 } |
| 252 | 263 |
| 253 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, | 264 int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, |
| 254 PP_CompletionCallback callback) { | 265 PP_CompletionCallback callback) { |
| 255 // Check state. | 266 // Check state. |
| 256 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || | 267 if (state_ == PP_WEBSOCKETREADYSTATE_INVALID_DEV || |
| 257 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 268 state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| 258 return PP_ERROR_BADARGUMENT; | 269 return PP_ERROR_BADARGUMENT; |
| 259 | 270 |
| 260 // Just return received message if any received message is queued. | 271 // Just return received message if any received message is queued. |
| 261 if (!received_messages_.empty()) | 272 if (!received_messages_.empty()) |
| 262 return DoReceive(); | 273 return DoReceive(); |
| 263 | 274 |
| 275 // Check state again. In CLOSED state, no more messages will be received. |
| 276 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
| 277 return PP_ERROR_BADARGUMENT; |
| 278 |
| 264 // Returns PP_ERROR_FAILED after an error is received and received messages | 279 // Returns PP_ERROR_FAILED after an error is received and received messages |
| 265 // is exhausted. | 280 // is exhausted. |
| 266 if (error_was_received_) | 281 if (error_was_received_) |
| 267 return PP_ERROR_FAILED; | 282 return PP_ERROR_FAILED; |
| 268 | 283 |
| 269 // Validate |callback| (Doesn't support blocking callback) | 284 // Validate |callback| (Doesn't support blocking callback) |
| 270 if (!callback.func) | 285 if (!callback.func) |
| 271 return PP_ERROR_BLOCKS_MAIN_THREAD; | 286 return PP_ERROR_BLOCKS_MAIN_THREAD; |
| 272 | 287 |
| 273 // Or retain |message| as buffer to store and install |callback|. | 288 // Or retain |message| as buffer to store and install |callback|. |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 // Records the error, then stops receiving any frames after this error. | 422 // Records the error, then stops receiving any frames after this error. |
| 408 // The error will be notified after all queued messages are read via | 423 // The error will be notified after all queued messages are read via |
| 409 // ReceiveMessage(). | 424 // ReceiveMessage(). |
| 410 error_was_received_ = true; | 425 error_was_received_ = true; |
| 411 if (!wait_for_receive_) | 426 if (!wait_for_receive_) |
| 412 return; | 427 return; |
| 413 | 428 |
| 414 // But, if no messages are queued and ReceiveMessage() is now on going. | 429 // But, if no messages are queued and ReceiveMessage() is now on going. |
| 415 // We must invoke the callback with error code here. | 430 // We must invoke the callback with error code here. |
| 416 wait_for_receive_ = false; | 431 wait_for_receive_ = false; |
| 432 receive_callback_var_ = NULL; |
| 417 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_FAILED); | 433 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_FAILED); |
| 418 } | 434 } |
| 419 | 435 |
| 420 void PPB_WebSocket_Impl::didUpdateBufferedAmount( | 436 void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
| 421 unsigned long buffered_amount) { | 437 unsigned long buffered_amount) { |
| 422 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) | 438 if (state_ == PP_WEBSOCKETREADYSTATE_CLOSED_DEV) |
| 423 return; | 439 return; |
| 424 buffered_amount_ = buffered_amount; | 440 buffered_amount_ = buffered_amount; |
| 425 } | 441 } |
| 426 | 442 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 447 | 463 |
| 448 // Update buffered_amount_. | 464 // Update buffered_amount_. |
| 449 buffered_amount_ = unhandled_buffered_amount; | 465 buffered_amount_ = unhandled_buffered_amount; |
| 450 | 466 |
| 451 // Handle state transition and invoking callback. | 467 // Handle state transition and invoking callback. |
| 452 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); | 468 DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
| 453 PP_WebSocketReadyState_Dev state = state_; | 469 PP_WebSocketReadyState_Dev state = state_; |
| 454 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; | 470 state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
| 455 | 471 |
| 456 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) | 472 if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| 457 PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); | 473 PP_RunAndClearCompletionCallback(&connect_callback_, PP_ERROR_FAILED); |
| 474 |
| 475 if (wait_for_receive_) { |
| 476 wait_for_receive_ = false; |
| 477 receive_callback_var_ = NULL; |
| 478 PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_ABORTED); |
| 479 } |
| 458 | 480 |
| 459 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) | 481 if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
| 460 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); | 482 PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
| 461 | 483 |
| 462 // Disconnect. | 484 // Disconnect. |
| 463 if (websocket_.get()) | 485 if (websocket_.get()) |
| 464 websocket_->disconnect(); | 486 websocket_->disconnect(); |
| 465 } | 487 } |
| 466 | 488 |
| 467 int32_t PPB_WebSocket_Impl::DoReceive() { | 489 int32_t PPB_WebSocket_Impl::DoReceive() { |
| 468 if (!receive_callback_var_) | 490 if (!receive_callback_var_) |
| 469 return PP_OK; | 491 return PP_OK; |
| 470 | 492 |
| 471 *receive_callback_var_ = received_messages_.front(); | 493 *receive_callback_var_ = received_messages_.front(); |
| 472 received_messages_.pop(); | 494 received_messages_.pop(); |
| 473 receive_callback_var_ = NULL; | 495 receive_callback_var_ = NULL; |
| 474 wait_for_receive_ = false; | 496 wait_for_receive_ = false; |
| 475 return PP_OK; | 497 return PP_OK; |
| 476 } | 498 } |
| 477 | 499 |
| 478 } // namespace ppapi | 500 } // namespace ppapi |
| 479 } // namespace webkit | 501 } // namespace webkit |
| OLD | NEW |