summaryrefslogtreecommitdiffstats
path: root/net/websockets
diff options
context:
space:
mode:
authorricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-19 08:27:47 +0000
committerricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-19 08:27:47 +0000
commitd52c0c46bfc9f7234e9e04fe95b0dfa5f4167304 (patch)
tree993d9f7ccde6d599355fb299c42a0f6d685a6dfe /net/websockets
parent08af935f3803c4be21409b79fb8eb23636889c42 (diff)
downloadchromium_src-d52c0c46bfc9f7234e9e04fe95b0dfa5f4167304.zip
chromium_src-d52c0c46bfc9f7234e9e04fe95b0dfa5f4167304.tar.gz
chromium_src-d52c0c46bfc9f7234e9e04fe95b0dfa5f4167304.tar.bz2
Clear reserved flags on synthetic continuations.
Previously when WebSocketBasicStream split a frame that arrived in several chunks, it would copy the reserved bits from the first frame onto all subsequent frames. However, the permessage-deflate extension requires that the RSV1 bit only be set on the first frame of the message. For compatability with permessage-deflate, clear the reserved bits on second and subsequent frames when splitting a frame. BUG=343507 TEST=net_unittests --gtest_filter=WebSocket* Review URL: https://codereview.chromium.org/171883002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252000 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/websockets')
-rw-r--r--net/websockets/websocket_basic_stream.cc11
-rw-r--r--net/websockets/websocket_basic_stream_test.cc27
2 files changed, 36 insertions, 2 deletions
diff --git a/net/websockets/websocket_basic_stream.cc b/net/websockets/websocket_basic_stream.cc
index 8d1fa87..fd2766b 100644
--- a/net/websockets/websocket_basic_stream.cc
+++ b/net/websockets/websocket_basic_stream.cc
@@ -378,9 +378,16 @@ scoped_ptr<WebSocketFrame> WebSocketBasicStream::CreateFrame(
result_frame->header.payload_length = data_size;
result_frame->data = data;
// Ensure that opcodes Text and Binary are only used for the first frame in
- // the message.
- if (WebSocketFrameHeader::IsKnownDataOpCode(opcode))
+ // the message. Also clear the reserved bits.
+ // TODO(ricea): If a future extension requires the reserved bits to be
+ // retained on continuation frames, make this behaviour conditional on a
+ // flag set at construction time.
+ if (!is_final_chunk && WebSocketFrameHeader::IsKnownDataOpCode(opcode)) {
current_frame_header_->opcode = WebSocketFrameHeader::kOpCodeContinuation;
+ current_frame_header_->reserved1 = false;
+ current_frame_header_->reserved2 = false;
+ current_frame_header_->reserved3 = false;
+ }
}
// Make sure that a frame header is not applied to any chunks that do not
// belong to it.
diff --git a/net/websockets/websocket_basic_stream_test.cc b/net/websockets/websocket_basic_stream_test.cc
index 85f6156..4dcb8e2 100644
--- a/net/websockets/websocket_basic_stream_test.cc
+++ b/net/websockets/websocket_basic_stream_test.cc
@@ -828,6 +828,33 @@ TEST_F(WebSocketBasicStreamSocketChunkedReadTest, OneMegFrame) {
}
}
+// A frame with reserved flag(s) set that arrives in chunks should only have the
+// reserved flag(s) set on the first chunk when split.
+TEST_F(WebSocketBasicStreamSocketChunkedReadTest, ReservedFlagCleared) {
+ static const char kReservedFlagFrame[] = "\x41\x05Hello";
+ const size_t kReservedFlagFrameSize = arraysize(kReservedFlagFrame) - 1;
+ const size_t kChunkSize = 5;
+
+ CreateChunkedRead(ASYNC,
+ kReservedFlagFrame,
+ kReservedFlagFrameSize,
+ kChunkSize,
+ 2,
+ LAST_FRAME_BIG);
+
+ TestCompletionCallback cb[2];
+ ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[0].callback()));
+ EXPECT_EQ(OK, cb[0].WaitForResult());
+ ASSERT_EQ(1U, frames_.size());
+ EXPECT_TRUE(frames_[0]->header.reserved1);
+
+ frames_.clear();
+ ASSERT_EQ(ERR_IO_PENDING, stream_->ReadFrames(&frames_, cb[1].callback()));
+ EXPECT_EQ(OK, cb[1].WaitForResult());
+ ASSERT_EQ(1U, frames_.size());
+ EXPECT_FALSE(frames_[0]->header.reserved1);
+}
+
// Check that writing a frame all at once works.
TEST_F(WebSocketBasicStreamSocketWriteTest, WriteAtOnce) {
MockWrite writes[] = {MockWrite(SYNCHRONOUS, kWriteFrame, kWriteFrameSize)};