Chromium Code Reviews| Index: webkit/plugins/ppapi/ppb_websocket_impl.cc |
| diff --git a/webkit/plugins/ppapi/ppb_websocket_impl.cc b/webkit/plugins/ppapi/ppb_websocket_impl.cc |
| index ea3634b876beddfc24aa48ef1007ddf3c784ea3c..b1e0054081f7043d020ff707808a096fc32d2ba4 100644 |
| --- a/webkit/plugins/ppapi/ppb_websocket_impl.cc |
| +++ b/webkit/plugins/ppapi/ppb_websocket_impl.cc |
| @@ -64,6 +64,13 @@ uint64_t GetFrameSize(uint64_t payload_size) { |
| return SaturateAdd(payload_size, overhead); |
| } |
| +bool InValidStateToReceive(PP_WebSocketReadyState_Dev state) { |
| + if (state != PP_WEBSOCKETREADYSTATE_OPEN_DEV && |
| + state != PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
| + return false; |
| + return true; |
|
dmichael (off chromium)
2011/12/02 16:28:09
suggestion/nit: could also have just been:
return
Takashi Toyoshima
2011/12/02 17:15:42
Sounds good.
Fixed.
|
| +} |
| + |
| } // namespace |
| namespace webkit { |
| @@ -72,6 +79,7 @@ namespace ppapi { |
| PPB_WebSocket_Impl::PPB_WebSocket_Impl(PP_Instance instance) |
| : Resource(instance), |
| state_(PP_WEBSOCKETREADYSTATE_INVALID_DEV), |
| + error_was_received_(false), |
| receive_callback_var_(NULL), |
| wait_for_receive_(false), |
| close_code_(0), |
| @@ -249,10 +257,19 @@ int32_t PPB_WebSocket_Impl::ReceiveMessage(PP_Var* message, |
| state_ == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| return PP_ERROR_BADARGUMENT; |
| + // Validate |callback| (Doesn't support blocking callback) |
| + if (!callback.func) |
| + return PP_ERROR_BLOCKS_MAIN_THREAD; |
| + |
| // Just return received message if any received message is queued. |
| if (!received_messages_.empty()) |
| return DoReceive(); |
| + // Returns PP_ERROR_FAILED after an error is received and received messages |
| + // is exhausted. |
| + if (error_was_received_) |
| + return PP_ERROR_FAILED; |
| + |
| // Or retain |message| as buffer to store and install |callback|. |
| wait_for_receive_ = true; |
| receive_callback_var_ = message; |
| @@ -357,6 +374,10 @@ void PPB_WebSocket_Impl::didConnect() { |
| } |
| void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { |
| + // Dispose packets after receiving an error or in invalid state. |
| + if (error_was_received_ || !InValidStateToReceive(state_)) |
| + return; |
| + |
| // Append received data to queue. |
| std::string string = message.utf8(); |
| PP_Var var = StringVar::StringToPPVar( |
| @@ -370,13 +391,30 @@ void PPB_WebSocket_Impl::didReceiveMessage(const WebString& message) { |
| } |
| void PPB_WebSocket_Impl::didReceiveBinaryData(const WebData& binaryData) { |
| - DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
| + // Dispose packets after receiving an error or in invalid state. |
| + if (error_was_received_ || !InValidStateToReceive(state_)) |
| + return; |
| + |
| // TODO(toyoshim): Support to receive binary data. |
| + DLOG(INFO) << "didReceiveBinaryData is not implemented yet."; |
| } |
| void PPB_WebSocket_Impl::didReceiveMessageError() { |
| - // TODO(toyoshim): Must implement. |
| - DLOG(INFO) << "didReceiveMessageError is not implemented yet."; |
| + // Ignore error notification in invalid state. |
| + if (!InValidStateToReceive(state_)) |
| + return; |
| + |
| + // Records the error, then stops receiving any frames after this error. |
| + // The error will be notified after all queued messages are read via |
| + // ReceiveMessage(). |
| + error_was_received_ = true; |
| + if (!wait_for_receive_) |
| + return; |
| + |
| + // But, if no messages is queued and ReceiveMessage() is now on going. |
|
dmichael (off chromium)
2011/12/02 16:28:09
nit: is -> are
Takashi Toyoshima
2011/12/02 17:15:42
Done.
|
| + // We must invoke the callback with error code here. |
| + wait_for_receive_ = false; |
| + PP_RunAndClearCompletionCallback(&receive_callback_, PP_ERROR_FAILED); |
| } |
| void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
| @@ -387,11 +425,10 @@ void PPB_WebSocket_Impl::didUpdateBufferedAmount( |
| } |
| void PPB_WebSocket_Impl::didStartClosingHandshake() { |
| - // TODO(toyoshim): Must implement. |
| - DLOG(INFO) << "didStartClosingHandshake is not implemented yet."; |
| + state_ = PP_WEBSOCKETREADYSTATE_CLOSING_DEV; |
| } |
| -void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, |
| +void PPB_WebSocket_Impl::didClose(unsigned long unhandled_buffered_amount, |
| ClosingHandshakeCompletionStatus status, |
| unsigned short code, |
| const WebString& reason) { |
| @@ -401,26 +438,33 @@ void PPB_WebSocket_Impl::didClose(unsigned long buffered_amount, |
| close_reason_ = new StringVar( |
| PpapiGlobals::Get()->GetModuleForInstance(pp_instance()), reason_string); |
| - // TODO(toyoshim): Set close_was_clean_. |
| + // Set close_was_clean_. |
| + bool was_clean = |
| + state_ == PP_WEBSOCKETREADYSTATE_CLOSING_DEV && |
| + !unhandled_buffered_amount && |
| + status == WebSocketClient::ClosingHandshakeComplete; |
| + close_was_clean_ = was_clean ? PP_TRUE : PP_FALSE; |
| + |
| + // Update buffered_amount_. |
| + buffered_amount_ = unhandled_buffered_amount; |
| // Handle state transition and invoking callback. |
| DCHECK_NE(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, state_); |
| PP_WebSocketReadyState_Dev state = state_; |
| state_ = PP_WEBSOCKETREADYSTATE_CLOSED_DEV; |
| - // Update buffered_amount_. |
| - buffered_amount_ = buffered_amount; |
| - |
| if (state == PP_WEBSOCKETREADYSTATE_CONNECTING_DEV) |
| PP_RunAndClearCompletionCallback(&connect_callback_, PP_OK); |
| if (state == PP_WEBSOCKETREADYSTATE_CLOSING_DEV) |
| PP_RunAndClearCompletionCallback(&close_callback_, PP_OK); |
| + |
| + // Disconnect. |
| + if (websocket_.get()) |
| + websocket_->disconnect(); |
| } |
| int32_t PPB_WebSocket_Impl::DoReceive() { |
| - // TODO(toyoshim): Check state. |
| - |
| if (!receive_callback_var_) |
| return PP_OK; |