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