diff options
author | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-19 08:27:47 +0000 |
---|---|---|
committer | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-19 08:27:47 +0000 |
commit | d52c0c46bfc9f7234e9e04fe95b0dfa5f4167304 (patch) | |
tree | 993d9f7ccde6d599355fb299c42a0f6d685a6dfe /net/websockets | |
parent | 08af935f3803c4be21409b79fb8eb23636889c42 (diff) | |
download | chromium_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.cc | 11 | ||||
-rw-r--r-- | net/websockets/websocket_basic_stream_test.cc | 27 |
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)}; |