summaryrefslogtreecommitdiffstats
path: root/net/websockets
diff options
context:
space:
mode:
authortyoshino@chromium.org <tyoshino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-19 16:48:22 +0000
committertyoshino@chromium.org <tyoshino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-19 16:48:22 +0000
commit3d563769f1f14cfd51a0320eb45ee92dc52c5aa1 (patch)
tree161fa00935ce5dfef14f622f13ff44a3d68fe084 /net/websockets
parentf9b7eeab4dd12df02205de7a76daf295ff3d125b (diff)
downloadchromium_src-3d563769f1f14cfd51a0320eb45ee92dc52c5aa1.zip
chromium_src-3d563769f1f14cfd51a0320eb45ee92dc52c5aa1.tar.gz
chromium_src-3d563769f1f14cfd51a0320eb45ee92dc52c5aa1.tar.bz2
[WebSocketChannel] Change |state_| out of SendClose() to make state transition clearer
BUG=none Review URL: https://codereview.chromium.org/196223006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258005 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/websockets')
-rw-r--r--net/websockets/websocket_channel.cc34
-rw-r--r--net/websockets/websocket_channel.h2
2 files changed, 23 insertions, 13 deletions
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc
index e8122b6..ed8a92b 100644
--- a/net/websockets/websocket_channel.cc
+++ b/net/websockets/websocket_channel.cc
@@ -395,13 +395,16 @@ void WebSocketChannel::StartClosingHandshake(uint16 code,
// errata 3227 to RFC6455. If the renderer is sending us an invalid code or
// reason it must be malfunctioning in some way, and based on that we
// interpret this as an internal error.
- AllowUnused(SendClose(kWebSocketErrorInternalServerError, ""));
- // |this| may have been deleted.
+ if (SendClose(kWebSocketErrorInternalServerError, "") != CHANNEL_DELETED)
+ state_ = SEND_CLOSED;
return;
}
- AllowUnused(SendClose(
- code, StreamingUtf8Validator::Validate(reason) ? reason : std::string()));
- // |this| may have been deleted.
+ if (SendClose(
+ code,
+ StreamingUtf8Validator::Validate(reason) ? reason : std::string()) ==
+ CHANNEL_DELETED)
+ return;
+ state_ = SEND_CLOSED;
}
void WebSocketChannel::SendAddChannelRequestForTesting(
@@ -520,6 +523,8 @@ ChannelState WebSocketChannel::WriteFrames() {
if (result != ERR_IO_PENDING) {
if (OnWriteDone(true, result) == CHANNEL_DELETED)
return CHANNEL_DELETED;
+ // OnWriteDone() returns CHANNEL_DELETED on error. Here |state_| is
+ // guaranteed to be the same as before OnWriteDone() call.
}
} while (result == OK && data_being_sent_);
return CHANNEL_ALIVE;
@@ -717,9 +722,10 @@ ChannelState WebSocketChannel::HandleFrameByState(
switch (state_) {
case CONNECTED:
state_ = RECV_CLOSED;
- if (SendClose(code, reason) == // Sets state_ to CLOSE_WAIT
- CHANNEL_DELETED)
+ if (SendClose(code, reason) == CHANNEL_DELETED)
return CHANNEL_DELETED;
+ state_ = CLOSE_WAIT;
+
if (event_interface_->OnClosingHandshake() == CHANNEL_DELETED)
return CHANNEL_DELETED;
received_close_code_ = code;
@@ -821,12 +827,14 @@ ChannelState WebSocketChannel::SendIOBuffer(
size_t size) {
DCHECK(state_ == CONNECTED || state_ == RECV_CLOSED);
DCHECK(stream_);
+
scoped_ptr<WebSocketFrame> frame(new WebSocketFrame(op_code));
WebSocketFrameHeader& header = frame->header;
header.final = fin;
header.masked = true;
header.payload_length = size;
frame->data = buffer;
+
if (data_being_sent_) {
// Either the link to the WebSocket server is saturated, or several messages
// are being sent in a batch.
@@ -837,6 +845,7 @@ ChannelState WebSocketChannel::SendIOBuffer(
data_to_send_next_->AddFrame(frame.Pass());
return CHANNEL_ALIVE;
}
+
data_being_sent_.reset(new SendBuffer);
data_being_sent_->AddFrame(frame.Pass());
return WriteFrames();
@@ -850,8 +859,7 @@ ChannelState WebSocketChannel::FailChannel(const std::string& message,
DCHECK_NE(CLOSED, state_);
// TODO(ricea): Logging.
if (state_ == CONNECTED) {
- if (SendClose(code, reason) == // Sets state_ to SEND_CLOSED
- CHANNEL_DELETED)
+ if (SendClose(code, reason) == CHANNEL_DELETED)
return CHANNEL_DELETED;
}
// Careful study of RFC6455 section 7.1.7 and 7.1.1 indicates the browser
@@ -893,9 +901,6 @@ ChannelState WebSocketChannel::SendClose(uint16 code,
if (SendIOBuffer(true, WebSocketFrameHeader::kOpCodeClose, body, size) ==
CHANNEL_DELETED)
return CHANNEL_DELETED;
- // SendIOBuffer() checks |state_|, so it is best not to change it until after
- // SendIOBuffer() returns.
- state_ = (state_ == CONNECTED) ? SEND_CLOSED : CLOSE_WAIT;
return CHANNEL_ALIVE;
}
@@ -958,7 +963,10 @@ ChannelState WebSocketChannel::DoDropChannel(bool was_clean,
if (CHANNEL_DELETED ==
notification_sender_->SendImmediately(event_interface_.get()))
return CHANNEL_DELETED;
- return event_interface_->OnDropChannel(was_clean, code, reason);
+ ChannelState result =
+ event_interface_->OnDropChannel(was_clean, code, reason);
+ DCHECK_EQ(CHANNEL_DELETED, result);
+ return result;
}
void WebSocketChannel::CloseTimeout() {
diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h
index fa7a133..183f2be 100644
--- a/net/websockets/websocket_channel.h
+++ b/net/websockets/websocket_channel.h
@@ -263,6 +263,8 @@ class NET_EXPORT WebSocketChannel {
// Drop this channel.
// If there are pending opening handshake notifications, notify them
// before dropping.
+ //
+ // Always returns CHANNEL_DELETED.
ChannelState DoDropChannel(bool was_clean,
uint16 code,
const std::string& reason);