Chromium Code Reviews| Index: net/websockets/websocket_channel_test.cc |
| diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc |
| index 25e9cdc050865e86278f66f1c5584d4e9eb1e1b2..b01c03a15921fd08e50714bf4c88d7d5af50f813 100644 |
| --- a/net/websockets/websocket_channel_test.cc |
| +++ b/net/websockets/websocket_channel_test.cc |
| @@ -38,36 +38,32 @@ |
| namespace net { |
| -// Printing helpers to allow GoogleMock to print frame chunks. These are |
| -// explicitly designed to look like the static initialisation format we use in |
| -// these tests. They have to live in the net namespace in order to be found by |
| +// Printing helpers to allow GoogleMock to print frames. These are explicitly |
| +// designed to look like the static initialisation format we use in these |
| +// tests. They have to live in the net namespace in order to be found by |
| // GoogleMock; a nested anonymous namespace will not work. |
| std::ostream& operator<<(std::ostream& os, const WebSocketFrameHeader& header) { |
| - return os << "{" << (header.final ? "FINAL_FRAME" : "NOT_FINAL_FRAME") << ", " |
| + return os << (header.final ? "FINAL_FRAME" : "NOT_FINAL_FRAME") << ", " |
| << header.opcode << ", " |
| - << (header.masked ? "MASKED" : "NOT_MASKED") << ", " |
| - << header.payload_length << "}"; |
| + << (header.masked ? "MASKED" : "NOT_MASKED"); |
| } |
| -std::ostream& operator<<(std::ostream& os, const WebSocketFrameChunk& chunk) { |
| - os << "{"; |
| - if (chunk.header) { |
| - os << *chunk.header; |
| - } else { |
| - os << "{NO_HEADER}"; |
| +std::ostream& operator<<(std::ostream& os, const WebSocketFrame& frame) { |
| + os << "{" << frame.header << ", "; |
| + if (frame.data) { |
| + return os << "\"" << base::StringPiece(frame.data->data(), |
| + frame.header.payload_length) |
| + << "\"}"; |
| } |
| - return os << ", " << (chunk.final_chunk ? "FINAL_CHUNK" : "NOT_FINAL_CHUNK") |
| - << ", \"" |
| - << base::StringPiece(chunk.data->data(), chunk.data->size()) |
| - << "\"}"; |
| + return os << "NULL}"; |
| } |
| std::ostream& operator<<(std::ostream& os, |
| - const ScopedVector<WebSocketFrameChunk>& vector) { |
| + const ScopedVector<WebSocketFrame>& vector) { |
| os << "{"; |
| bool first = true; |
| - for (ScopedVector<WebSocketFrameChunk>::const_iterator it = vector.begin(); |
| + for (ScopedVector<WebSocketFrame>::const_iterator it = vector.begin(); |
| it != vector.end(); |
| ++it) { |
| if (!first) { |
| @@ -81,7 +77,7 @@ std::ostream& operator<<(std::ostream& os, |
| } |
| std::ostream& operator<<(std::ostream& os, |
| - const ScopedVector<WebSocketFrameChunk>* vector) { |
| + const ScopedVector<WebSocketFrame>* vector) { |
| return os << '&' << *vector; |
| } |
| @@ -97,7 +93,7 @@ using ::testing::_; |
| // A selection of characters that have traditionally been mangled in some |
| // environment or other, for testing 8-bit cleanliness. |
| -const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL |
| +const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL |
| '\0', // nul |
| '\x7F', // DEL |
| '\x80', '\xFF', // NOT VALID UTF-8 |
| @@ -170,12 +166,12 @@ class FakeWebSocketStream : public WebSocketStream { |
| return ERR_IO_PENDING; |
| } |
| - virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| return ERR_IO_PENDING; |
| } |
| - virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| return ERR_IO_PENDING; |
| } |
| @@ -198,12 +194,7 @@ class FakeWebSocketStream : public WebSocketStream { |
| // To make the static initialisers easier to read, we use enums rather than |
| // bools. |
| - |
| -// NO_HEADER means there shouldn't be a header included in the generated |
| -// WebSocketFrameChunk. The static initialiser always has a header, but we can |
| -// avoid specifying the rest of the fields. |
| enum IsFinal { |
| - NO_HEADER, |
| NOT_FINAL_FRAME, |
| FINAL_FRAME |
| }; |
| @@ -213,54 +204,33 @@ enum IsMasked { |
| MASKED |
| }; |
| -enum IsFinalChunk { |
| - NOT_FINAL_CHUNK, |
| - FINAL_CHUNK |
| -}; |
| - |
| -// This is used to initialise a WebSocketFrameChunk but is statically |
| -// initialisable. |
| -struct InitFrameChunk { |
| - struct FrameHeader { |
| - IsFinal final; |
| - // Reserved fields omitted for now. Add them if you need them. |
| - WebSocketFrameHeader::OpCode opcode; |
| - IsMasked masked; |
| - // payload_length is the length of the whole frame. The length of the data |
| - // members from every chunk in the frame must add up to the payload_length. |
| - uint64 payload_length; |
| - }; |
| - FrameHeader header; |
| - |
| - // Directly equivalent to WebSocketFrameChunk::final_chunk |
| - IsFinalChunk final_chunk; |
| +// This is used to initialise a WebSocketFrame but is statically initialisable. |
| +struct InitFrame { |
| + IsFinal final; |
| + // Reserved fields omitted for now. Add them if you need them. |
| + WebSocketFrameHeader::OpCode opcode; |
| + IsMasked masked; |
| // Will be used to create the IOBuffer member. Can be NULL for NULL data. Is a |
| - // nul-terminated string for ease-of-use. This means it is not 8-bit clean, |
| - // but this is not an issue for test data. |
| + // nul-terminated string for ease-of-use. |header.payload_length| is |
| + // initialised from |strlen(data)|. This means it is not 8-bit clean, but this |
| + // is not an issue for test data. |
| const char* const data; |
| }; |
| // For GoogleMock |
| -std::ostream& operator<<(std::ostream& os, const InitFrameChunk& chunk) { |
| - os << "{"; |
| - if (chunk.header.final != NO_HEADER) { |
| - os << "{" << (chunk.header.final == FINAL_FRAME ? "FINAL_FRAME" |
| - : "NOT_FINAL_FRAME") << ", " |
| - << chunk.header.opcode << ", " |
| - << (chunk.header.masked == MASKED ? "MASKED" : "NOT_MASKED") << ", " |
| - << chunk.header.payload_length << "}"; |
| - |
| - } else { |
| - os << "{NO_HEADER}"; |
| +std::ostream& operator<<(std::ostream& os, const InitFrame& frame) { |
| + os << "{" << (frame.final == FINAL_FRAME ? "FINAL_FRAME" : "NOT_FINAL_FRAME") |
| + << ", " << frame.opcode << ", " |
| + << (frame.masked == MASKED ? "MASKED" : "NOT_MASKED") << ", "; |
| + if (frame.data) { |
| + return os << "\"" << frame.data << "\"}"; |
| } |
| - return os << ", " << (chunk.final_chunk == FINAL_CHUNK ? "FINAL_CHUNK" |
| - : "NOT_FINAL_CHUNK") |
| - << ", \"" << chunk.data << "\"}"; |
| + return os << "NULL}"; |
| } |
| template <size_t N> |
| -std::ostream& operator<<(std::ostream& os, const InitFrameChunk (&chunks)[N]) { |
| +std::ostream& operator<<(std::ostream& os, const InitFrame (&frames)[N]) { |
| os << "{"; |
| bool first = true; |
| for (size_t i = 0; i < N; ++i) { |
| @@ -269,119 +239,92 @@ std::ostream& operator<<(std::ostream& os, const InitFrameChunk (&chunks)[N]) { |
| } else { |
| first = false; |
| } |
| - os << chunks[i]; |
| + os << frames[i]; |
| } |
| return os << "}"; |
| } |
| -// Convert a const array of InitFrameChunks to the format used at |
| +// Convert a const array of InitFrame structs to the format used at |
| // runtime. Templated on the size of the array to save typing. |
| template <size_t N> |
| -ScopedVector<WebSocketFrameChunk> CreateFrameChunkVector( |
| - const InitFrameChunk (&source_chunks)[N]) { |
| - ScopedVector<WebSocketFrameChunk> result_chunks; |
| - result_chunks.reserve(N); |
| +ScopedVector<WebSocketFrame> CreateFrameVector( |
| + const InitFrame (&source_frames)[N]) { |
| + ScopedVector<WebSocketFrame> result_frames; |
| + result_frames.reserve(N); |
| for (size_t i = 0; i < N; ++i) { |
| - scoped_ptr<WebSocketFrameChunk> result_chunk(new WebSocketFrameChunk); |
| - size_t chunk_length = |
| - source_chunks[i].data ? strlen(source_chunks[i].data) : 0; |
| - if (source_chunks[i].header.final != NO_HEADER) { |
| - const InitFrameChunk::FrameHeader& source_header = |
| - source_chunks[i].header; |
| - scoped_ptr<WebSocketFrameHeader> result_header( |
| - new WebSocketFrameHeader(source_header.opcode)); |
| - result_header->final = (source_header.final == FINAL_FRAME); |
| - result_header->masked = (source_header.masked == MASKED); |
| - result_header->payload_length = source_header.payload_length; |
| - DCHECK(chunk_length <= source_header.payload_length); |
| - result_chunk->header.swap(result_header); |
| - } |
| - result_chunk->final_chunk = (source_chunks[i].final_chunk == FINAL_CHUNK); |
| - if (source_chunks[i].data) { |
| - result_chunk->data = new IOBufferWithSize(chunk_length); |
| - memcpy(result_chunk->data->data(), source_chunks[i].data, chunk_length); |
| + const InitFrame& source_frame = source_frames[i]; |
| + scoped_ptr<WebSocketFrame> result_frame( |
| + new WebSocketFrame(source_frame.opcode)); |
| + size_t frame_length = source_frame.data ? strlen(source_frame.data) : 0; |
| + WebSocketFrameHeader& result_header = result_frame->header; |
| + result_header.final = (source_frame.final == FINAL_FRAME); |
| + result_header.masked = (source_frame.masked == MASKED); |
| + result_header.payload_length = frame_length; |
| + if (source_frames[i].data) { |
|
tyoshino (SeeGerritForStatus)
2013/09/26 05:59:04
source_frames[i] -> source_frame
Adam Rice
2013/09/26 06:25:55
Sorry I missed this. Done.
|
| + result_frame->data = new IOBuffer(frame_length); |
| + memcpy(result_frame->data->data(), source_frames[i].data, frame_length); |
|
tyoshino (SeeGerritForStatus)
2013/09/26 05:59:04
source_frames[i] -> source_frame
Adam Rice
2013/09/26 06:25:55
Done.
|
| } |
| - result_chunks.push_back(result_chunk.release()); |
| + result_frames.push_back(result_frame.release()); |
| } |
| - return result_chunks.Pass(); |
| + return result_frames.Pass(); |
| } |
| // A GoogleMock action which can be used to respond to call to ReadFrames with |
| -// some frames. Use like ReadFrames(_, _).WillOnce(ReturnChunks(&chunks)); |
| -// |chunks| is an array of InitFrameChunks needs to be passed by pointer because |
| -// otherwise it will be reduced to a pointer and lose the array size |
| -// information. |
| -ACTION_P(ReturnChunks, source_chunks) { |
| - *arg0 = CreateFrameChunkVector(*source_chunks); |
| +// some frames. Use like ReadFrames(_, _).WillOnce(ReturnFrames(&frames)); |
| +// |frames| is an array of InitFrame. |frames| needs to be passed by pointer |
| +// because otherwise it will be treated as a pointer and the array size |
| +// information will be lost. |
| +ACTION_P(ReturnFrames, source_frames) { |
| + *arg0 = CreateFrameVector(*source_frames); |
| return OK; |
| } |
| // The implementation of a GoogleMock matcher which can be used to compare a |
| -// ScopedVector<WebSocketFrameChunk>* against an expectation defined as an array |
| -// of InitFrameChunks. Although it is possible to compose built-in GoogleMock |
| -// matchers to check the contents of a WebSocketFrameChunk, the results are so |
| +// ScopedVector<WebSocketFrame>* against an expectation defined as an array of |
| +// InitFrame objects. Although it is possible to compose built-in GoogleMock |
| +// matchers to check the contents of a WebSocketFrame, the results are so |
| // unreadable that it is better to use this matcher. |
| template <size_t N> |
| -class EqualsChunksMatcher |
| - : public ::testing::MatcherInterface<ScopedVector<WebSocketFrameChunk>*> { |
| +class EqualsFramesMatcher |
| + : public ::testing::MatcherInterface<ScopedVector<WebSocketFrame>*> { |
| public: |
| - EqualsChunksMatcher(const InitFrameChunk (*expect_chunks)[N]) |
| - : expect_chunks_(expect_chunks) {} |
| + EqualsFramesMatcher(const InitFrame (*expect_frames)[N]) |
| + : expect_frames_(expect_frames) {} |
| - virtual bool MatchAndExplain(ScopedVector<WebSocketFrameChunk>* actual_chunks, |
| + virtual bool MatchAndExplain(ScopedVector<WebSocketFrame>* actual_frames, |
| ::testing::MatchResultListener* listener) const { |
| - if (actual_chunks->size() != N) { |
| - *listener << "the vector size is " << actual_chunks->size(); |
| + if (actual_frames->size() != N) { |
| + *listener << "the vector size is " << actual_frames->size(); |
| return false; |
| } |
| for (size_t i = 0; i < N; ++i) { |
| - const WebSocketFrameChunk& actual_chunk = *(*actual_chunks)[i]; |
| - const InitFrameChunk& expected_chunk = (*expect_chunks_)[i]; |
| - // Testing that the absence or presence of a header is the same for both. |
| - if ((!actual_chunk.header) != |
| - (expected_chunk.header.final == NO_HEADER)) { |
| - *listener << "the header is " |
| - << (actual_chunk.header ? "present" : "absent"); |
| + const WebSocketFrame& actual_frame = *(*actual_frames)[i]; |
| + const InitFrame& expected_frame = (*expect_frames_)[i]; |
| + if (actual_frame.header.final != (expected_frame.final == FINAL_FRAME)) { |
| + *listener << "the frame is marked as " |
| + << (actual_frame.header.final ? "" : "not ") << "final"; |
| return false; |
| } |
| - if (actual_chunk.header) { |
| - if (actual_chunk.header->final != |
| - (expected_chunk.header.final == FINAL_FRAME)) { |
| - *listener << "the frame is marked as " |
| - << (actual_chunk.header->final ? "" : "not ") << "final"; |
| - return false; |
| - } |
| - if (actual_chunk.header->opcode != expected_chunk.header.opcode) { |
| - *listener << "the opcode is " << actual_chunk.header->opcode; |
| - return false; |
| - } |
| - if (actual_chunk.header->masked != |
| - (expected_chunk.header.masked == MASKED)) { |
| - *listener << "the frame is " |
| - << (actual_chunk.header->masked ? "masked" : "not masked"); |
| - return false; |
| - } |
| - if (actual_chunk.header->payload_length != |
| - expected_chunk.header.payload_length) { |
| - *listener << "the payload length is " |
| - << actual_chunk.header->payload_length; |
| - return false; |
| - } |
| + if (actual_frame.header.opcode != expected_frame.opcode) { |
| + *listener << "the opcode is " << actual_frame.header.opcode; |
| + return false; |
| } |
| - if (actual_chunk.final_chunk != |
| - (expected_chunk.final_chunk == FINAL_CHUNK)) { |
| - *listener << "the chunk is marked as " |
| - << (actual_chunk.final_chunk ? "" : "not ") << "final"; |
| + if (actual_frame.header.masked != (expected_frame.masked == MASKED)) { |
| + *listener << "the frame is " |
| + << (actual_frame.header.masked ? "masked" : "not masked"); |
| return false; |
| } |
| - if (actual_chunk.data->size() != |
| - base::checked_numeric_cast<int>(strlen(expected_chunk.data))) { |
| - *listener << "the data size is " << actual_chunk.data->size(); |
| + const size_t expected_length = |
| + expected_frame.data ? strlen(expected_frame.data) : 0; |
| + if (actual_frame.header.payload_length != expected_length) { |
| + *listener << "the payload length is " |
| + << actual_frame.header.payload_length; |
| return false; |
| } |
| - if (memcmp(actual_chunk.data->data(), |
| - expected_chunk.data, |
| - actual_chunk.data->size()) != 0) { |
| + if (expected_length != 0 && |
| + memcmp(actual_frame.data->data(), |
| + expected_frame.data, |
| + actual_frame.header.payload_length) != 0) { |
| *listener << "the data content differs"; |
| return false; |
| } |
| @@ -390,23 +333,23 @@ class EqualsChunksMatcher |
| } |
| virtual void DescribeTo(std::ostream* os) const { |
| - *os << "matches " << *expect_chunks_; |
| + *os << "matches " << *expect_frames_; |
| } |
| virtual void DescribeNegationTo(std::ostream* os) const { |
| - *os << "does not match " << *expect_chunks_; |
| + *os << "does not match " << *expect_frames_; |
| } |
| private: |
| - const InitFrameChunk (*expect_chunks_)[N]; |
| + const InitFrame (*expect_frames_)[N]; |
| }; |
| -// The definition of EqualsChunks GoogleMock matcher. Unlike the ReturnChunks |
| +// The definition of EqualsFrames GoogleMock matcher. Unlike the ReturnFrames |
| // action, this can take the array by reference. |
| template <size_t N> |
| -::testing::Matcher<ScopedVector<WebSocketFrameChunk>*> EqualsChunks( |
| - const InitFrameChunk (&chunks)[N]) { |
| - return ::testing::MakeMatcher(new EqualsChunksMatcher<N>(&chunks)); |
| +::testing::Matcher<ScopedVector<WebSocketFrame>*> EqualsFrames( |
| + const InitFrame (&frames)[N]) { |
| + return ::testing::MakeMatcher(new EqualsFramesMatcher<N>(&frames)); |
| } |
| // A FakeWebSocketStream whose ReadFrames() function returns data. |
| @@ -427,39 +370,38 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream { |
| CHECK(!read_frames_pending_); |
| } |
| - // Prepares a fake responses. Fake responses will be returned from |
| - // ReadFrames() in the same order they were prepared with PrepareReadFrames() |
| - // and PrepareReadFramesError(). If |async| is ASYNC, then ReadFrames() will |
| + // Prepares a fake response. Fake responses will be returned from ReadFrames() |
| + // in the same order they were prepared with PrepareReadFrames() and |
| + // PrepareReadFramesError(). If |async| is ASYNC, then ReadFrames() will |
| // return ERR_IO_PENDING and the callback will be scheduled to run on the |
| // message loop. This requires the test case to run the message loop. If |
| // |async| is SYNC, the response will be returned synchronously. |error| is |
| // returned directly from ReadFrames() in the synchronous case, or passed to |
| - // the callback in the asynchronous case. |chunks| will be converted to a |
| - // ScopedVector<WebSocketFrameChunks> and copied to the pointer that was |
| - // passed to ReadFrames(). |
| + // the callback in the asynchronous case. |frames| will be converted to a |
| + // ScopedVector<WebSocketFrame> and copied to the pointer that was passed to |
| + // ReadFrames(). |
| template <size_t N> |
| void PrepareReadFrames(IsSync async, |
| int error, |
| - const InitFrameChunk (&chunks)[N]) { |
| - responses_.push_back( |
| - new Response(async, error, CreateFrameChunkVector(chunks))); |
| + const InitFrame (&frames)[N]) { |
| + responses_.push_back(new Response(async, error, CreateFrameVector(frames))); |
| } |
| // An alternate version of PrepareReadFrames for when we need to construct |
| // the frames manually. |
| void PrepareRawReadFrames(IsSync async, |
| int error, |
| - ScopedVector<WebSocketFrameChunk> chunks) { |
| - responses_.push_back(new Response(async, error, chunks.Pass())); |
| + ScopedVector<WebSocketFrame> frames) { |
| + responses_.push_back(new Response(async, error, frames.Pass())); |
| } |
| // Prepares a fake error response (ie. there is no data). |
| void PrepareReadFramesError(IsSync async, int error) { |
| responses_.push_back( |
| - new Response(async, error, ScopedVector<WebSocketFrameChunk>())); |
| + new Response(async, error, ScopedVector<WebSocketFrame>())); |
| } |
| - virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| CHECK(!read_frames_pending_); |
| if (index_ >= responses_.size()) |
| @@ -470,34 +412,34 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream { |
| FROM_HERE, |
| base::Bind(&ReadableFakeWebSocketStream::DoCallback, |
| base::Unretained(this), |
| - frame_chunks, |
| + frames, |
| callback)); |
| return ERR_IO_PENDING; |
| } else { |
| - frame_chunks->swap(responses_[index_]->chunks); |
| + frames->swap(responses_[index_]->frames); |
| return responses_[index_++]->error; |
| } |
| } |
| private: |
| - void DoCallback(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + void DoCallback(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) { |
| read_frames_pending_ = false; |
| - frame_chunks->swap(responses_[index_]->chunks); |
| + frames->swap(responses_[index_]->frames); |
| callback.Run(responses_[index_++]->error); |
| return; |
| } |
| struct Response { |
| - Response(IsSync async, int error, ScopedVector<WebSocketFrameChunk> chunks) |
| - : async(async), error(error), chunks(chunks.Pass()) {} |
| + Response(IsSync async, int error, ScopedVector<WebSocketFrame> frames) |
| + : async(async), error(error), frames(frames.Pass()) {} |
| IsSync async; |
| int error; |
| - ScopedVector<WebSocketFrameChunk> chunks; |
| + ScopedVector<WebSocketFrame> frames; |
| private: |
| - // Bad things will happen if we attempt to copy or assign "chunks". |
| + // Bad things will happen if we attempt to copy or assign |frames|. |
| DISALLOW_COPY_AND_ASSIGN(Response); |
| }; |
| ScopedVector<Response> responses_; |
| @@ -516,7 +458,7 @@ class ReadableFakeWebSocketStream : public FakeWebSocketStream { |
| // synchronously. |
| class WriteableFakeWebSocketStream : public FakeWebSocketStream { |
| public: |
| - virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| return OK; |
| } |
| @@ -525,7 +467,7 @@ class WriteableFakeWebSocketStream : public FakeWebSocketStream { |
| // A FakeWebSocketStream where writes always fail. |
| class UnWriteableFakeWebSocketStream : public FakeWebSocketStream { |
| public: |
| - virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| return ERR_CONNECTION_RESET; |
| } |
| @@ -539,23 +481,22 @@ class UnWriteableFakeWebSocketStream : public FakeWebSocketStream { |
| // otherwise the ReadFrames() callback will never be called. |
| class EchoeyFakeWebSocketStream : public FakeWebSocketStream { |
| public: |
| - EchoeyFakeWebSocketStream() : read_frame_chunks_(NULL), done_(false) {} |
| + EchoeyFakeWebSocketStream() : read_frames_(NULL), done_(false) {} |
| - virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| // Users of WebSocketStream will not expect the ReadFrames() callback to be |
| // called from within WriteFrames(), so post it to the message loop instead. |
| - stored_frame_chunks_.insert( |
| - stored_frame_chunks_.end(), frame_chunks->begin(), frame_chunks->end()); |
| - frame_chunks->weak_clear(); |
| + stored_frames_.insert(stored_frames_.end(), frames->begin(), frames->end()); |
| + frames->weak_clear(); |
| PostCallback(); |
| return OK; |
| } |
| - virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| read_callback_ = callback; |
| - read_frame_chunks_ = frame_chunks; |
| + read_frames_ = frames; |
| if (done_) |
| PostCallback(); |
| return ERR_IO_PENDING; |
| @@ -572,36 +513,34 @@ class EchoeyFakeWebSocketStream : public FakeWebSocketStream { |
| void DoCallback() { |
| if (done_) { |
| read_callback_.Run(ERR_CONNECTION_CLOSED); |
| - } else if (!stored_frame_chunks_.empty()) { |
| - done_ = MoveFrameChunks(read_frame_chunks_); |
| - read_frame_chunks_ = NULL; |
| + } else if (!stored_frames_.empty()) { |
| + done_ = MoveFrames(read_frames_); |
| + read_frames_ = NULL; |
| read_callback_.Run(OK); |
| } |
| } |
| - // Copy the chunks stored in stored_frame_chunks_ to |out|, while clearing the |
| + // Copy the frames stored in stored_frames_ to |out|, while clearing the |
| // "masked" header bit. Returns true if a Close Frame was seen, false |
| // otherwise. |
| - bool MoveFrameChunks(ScopedVector<WebSocketFrameChunk>* out) { |
| + bool MoveFrames(ScopedVector<WebSocketFrame>* out) { |
| bool seen_close = false; |
| - *out = stored_frame_chunks_.Pass(); |
| - for (ScopedVector<WebSocketFrameChunk>::iterator it = out->begin(); |
| + *out = stored_frames_.Pass(); |
| + for (ScopedVector<WebSocketFrame>::iterator it = out->begin(); |
| it != out->end(); |
| ++it) { |
| - WebSocketFrameHeader* header = (*it)->header.get(); |
| - if (header) { |
| - header->masked = false; |
| - if (header->opcode == WebSocketFrameHeader::kOpCodeClose) |
| - seen_close = true; |
| - } |
| + WebSocketFrameHeader& header = (*it)->header; |
| + header.masked = false; |
| + if (header.opcode == WebSocketFrameHeader::kOpCodeClose) |
| + seen_close = true; |
| } |
| return seen_close; |
| } |
| - ScopedVector<WebSocketFrameChunk> stored_frame_chunks_; |
| + ScopedVector<WebSocketFrame> stored_frames_; |
| CompletionCallback read_callback_; |
| // Owned by the caller of ReadFrames(). |
| - ScopedVector<WebSocketFrameChunk>* read_frame_chunks_; |
| + ScopedVector<WebSocketFrame>* read_frames_; |
| // True if we should close the connection. |
| bool done_; |
| }; |
| @@ -612,7 +551,7 @@ class EchoeyFakeWebSocketStream : public FakeWebSocketStream { |
| // run the message loop. |
| class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { |
| public: |
| - virtual int WriteFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, base::Bind(callback, ERR_CONNECTION_RESET)); |
| @@ -621,7 +560,7 @@ class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { |
| return ERR_IO_PENDING; |
| } |
| - virtual int ReadFrames(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback) OVERRIDE { |
| read_callback_ = callback; |
| return ERR_IO_PENDING; |
| @@ -636,10 +575,10 @@ class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { |
| class MockWebSocketStream : public WebSocketStream { |
| public: |
| MOCK_METHOD2(ReadFrames, |
| - int(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + int(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback)); |
| MOCK_METHOD2(WriteFrames, |
| - int(ScopedVector<WebSocketFrameChunk>* frame_chunks, |
| + int(ScopedVector<WebSocketFrame>* frames, |
| const CompletionCallback& callback)); |
| MOCK_METHOD0(Close, void()); |
| MOCK_CONST_METHOD0(GetSubProtocol, std::string()); |
| @@ -846,8 +785,8 @@ TEST_F(WebSocketChannelTest, EverythingIsPassedToTheFactoryFunction) { |
| // AddressSanitizer. |
| TEST_F(WebSocketChannelDeletingTest, DeletingFromOnAddChannelResponseWorks) { |
| CreateChannelAndConnect(); |
| - connect_data_.factory.connect_delegate |
| - ->OnFailure(kWebSocketErrorNoStatusReceived); |
| + connect_data_.factory.connect_delegate->OnFailure( |
| + kWebSocketErrorNoStatusReceived); |
| EXPECT_EQ(NULL, channel_.get()); |
| } |
| @@ -869,8 +808,8 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) { |
| CreateChannelAndConnect(); |
| - connect_data_.factory.connect_delegate |
| - ->OnFailure(kWebSocketErrorNoStatusReceived); |
| + connect_data_.factory.connect_delegate->OnFailure( |
| + kWebSocketErrorNoStatusReceived); |
| } |
| TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { |
| @@ -889,10 +828,9 @@ TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { |
| TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, |
| - FINAL_CHUNK, "HELLO"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks); |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -912,10 +850,10 @@ TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) { |
| TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 23}, |
| - FINAL_CHUNK, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks); |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + NOT_MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, |
| ERR_CONNECTION_CLOSED); |
| set_stream(stream.Pass()); |
| @@ -954,13 +892,12 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) { |
| TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, |
| - FINAL_CHUNK, "HELLO"}}; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| // We use this checkpoint object to verify that the callback isn't called |
| // until we expect it to be. |
| MockFunction<void(int)> checkpoint; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -985,14 +922,12 @@ TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { |
| TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks1[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, |
| - FINAL_CHUNK, "HELLO"}}; |
| - static const InitFrameChunk chunks2[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, |
| - FINAL_CHUNK, "WORLD"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks2); |
| + static const InitFrame frames1[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; |
| + static const InitFrame frames2[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "WORLD"}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames2); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1012,31 +947,29 @@ TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) { |
| base::MessageLoop::current()->RunUntilIdle(); |
| } |
| -// Data frames that arrive in fragments are turned into individual frames |
| +// Data frames are delivered the same regardless of how many reads they arrive |
| +// as. |
| TEST_F(WebSocketChannelEventInterfaceTest, FragmentedFrames) { |
|
tyoshino (SeeGerritForStatus)
2013/09/26 05:59:04
FragmentedMessage would be better now.
Adam Rice
2013/09/26 06:25:55
Done.
|
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - // Here we have one message split into 3 frames which arrive in 3 chunks. The |
| - // first frame is entirely in the first chunk, the second frame is split |
| - // across all the chunks, and the final frame is entirely in the final |
| - // chunk. The frame fragments are converted to separate frames so that they |
| - // can be delivered immediatedly. So the EventInterface should see a Text |
| - // message with 5 frames. |
| - static const InitFrameChunk chunks1[] = { |
| - {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 5}, |
| - FINAL_CHUNK, "THREE"}, |
| - {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, |
| - 7}, |
| - NOT_FINAL_CHUNK, " "}}; |
| - static const InitFrameChunk chunks2[] = { |
| - {{NO_HEADER}, NOT_FINAL_CHUNK, "SMALL"}}; |
| - static const InitFrameChunk chunks3[] = { |
| - {{NO_HEADER}, FINAL_CHUNK, " "}, |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 6}, |
| - FINAL_CHUNK, "FRAMES"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3); |
| + // Here we have one message which arrived in five frames split across three |
| + // reads. It may have been reframed on arrival, but this class doesn't care |
| + // about that. |
| + static const InitFrame frames1[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "THREE"}, |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + NOT_MASKED, " "}}; |
| + static const InitFrame frames2[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + NOT_MASKED, "SMALL"}}; |
| + static const InitFrame frames3[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + NOT_MASKED, " "}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + NOT_MASKED, "FRAMES"}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1068,112 +1001,16 @@ TEST_F(WebSocketChannelEventInterfaceTest, FragmentedFrames) { |
| base::MessageLoop::current()->RunUntilIdle(); |
| } |
| -// In the case when a single-frame message because fragmented, it must be |
| -// correctly transformed to multiple frames. |
| -TEST_F(WebSocketChannelEventInterfaceTest, MessageFragmentation) { |
| - scoped_ptr<ReadableFakeWebSocketStream> stream( |
| - new ReadableFakeWebSocketStream); |
| - // A single-frame Text message arrives in three chunks. This should be |
| - // delivered as three frames. |
| - static const InitFrameChunk chunks1[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 12}, |
| - NOT_FINAL_CHUNK, "TIME"}}; |
| - static const InitFrameChunk chunks2[] = { |
| - {{NO_HEADER}, NOT_FINAL_CHUNK, " FOR "}}; |
| - static const InitFrameChunk chunks3[] = {{{NO_HEADER}, FINAL_CHUNK, "TEA"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3); |
| - set_stream(stream.Pass()); |
| - { |
| - InSequence s; |
| - EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| - EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| - EXPECT_CALL( |
| - *event_interface_, |
| - OnDataFrame( |
| - false, WebSocketFrameHeader::kOpCodeText, AsVector("TIME"))); |
| - EXPECT_CALL(*event_interface_, |
| - OnDataFrame(false, |
| - WebSocketFrameHeader::kOpCodeContinuation, |
| - AsVector(" FOR "))); |
| - EXPECT_CALL( |
| - *event_interface_, |
| - OnDataFrame( |
| - true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("TEA"))); |
| - } |
| - |
| - CreateChannelAndConnectSuccessfully(); |
| - base::MessageLoop::current()->RunUntilIdle(); |
| -} |
| - |
| -// If a control message is fragmented, it must be re-assembled before being |
| -// delivered. A control message can only be fragmented at the network level; it |
| -// is not permitted to be split into multiple frames. |
| -TEST_F(WebSocketChannelEventInterfaceTest, FragmentedControlMessage) { |
| - scoped_ptr<ReadableFakeWebSocketStream> stream( |
| - new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks1[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7}, |
| - NOT_FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "")}}; |
| - static const InitFrameChunk chunks2[] = { |
| - {{NO_HEADER}, NOT_FINAL_CHUNK, "Clo"}}; |
| - static const InitFrameChunk chunks3[] = {{{NO_HEADER}, FINAL_CHUNK, "se"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3); |
| - stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, |
| - ERR_CONNECTION_CLOSED); |
| - set_stream(stream.Pass()); |
| - { |
| - InSequence s; |
| - EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| - EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| - EXPECT_CALL(*event_interface_, OnClosingHandshake()); |
| - EXPECT_CALL(*event_interface_, |
| - OnDropChannel(kWebSocketNormalClosure, "Close")); |
| - } |
| - |
| - CreateChannelAndConnectSuccessfully(); |
| - base::MessageLoop::current()->RunUntilIdle(); |
| -} |
| - |
| -// The payload of a control frame is not permitted to exceed 125 bytes. RFC6455 |
| -// 5.5 "All control frames MUST have a payload length of 125 bytes or less" |
| -TEST_F(WebSocketChannelEventInterfaceTest, OversizeControlMessageIsRejected) { |
| - scoped_ptr<ReadableFakeWebSocketStream> stream( |
| - new ReadableFakeWebSocketStream); |
| - static const size_t kPayloadLen = 126; |
| - char payload[kPayloadLen + 1]; // allow space for trailing NUL |
| - std::fill(payload, payload + kPayloadLen, 'A'); |
| - payload[kPayloadLen] = '\0'; |
| - // Not static because "payload" is constructed at runtime. |
| - const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, |
| - kPayloadLen}, |
| - FINAL_CHUNK, payload}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks); |
| - set_stream(stream.Pass()); |
| - |
| - EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| - EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| - EXPECT_CALL(*event_interface_, |
| - OnDropChannel(kWebSocketErrorProtocolError, _)); |
| - |
| - CreateChannelAndConnectSuccessfully(); |
| -} |
| - |
| // A control frame is not permitted to be split into multiple frames. RFC6455 |
| // 5.5 "All control frames ... MUST NOT be fragmented." |
| TEST_F(WebSocketChannelEventInterfaceTest, MultiFrameControlMessageIsRejected) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 2}, |
| - FINAL_CHUNK, "Pi"}, |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 2}, |
| - FINAL_CHUNK, "ng"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); |
| + static const InitFrame frames[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, "Pi"}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + NOT_MASKED, "ng"}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1225,39 +1062,14 @@ TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) { |
| base::MessageLoop::current()->RunUntilIdle(); |
| } |
| -// Connection closed in the middle of a Close message (server bug, etc.) |
| -TEST_F(WebSocketChannelEventInterfaceTest, ConnectionClosedInMessage) { |
| - scoped_ptr<ReadableFakeWebSocketStream> stream( |
| - new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7}, |
| - NOT_FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "")}}; |
| - |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); |
| - stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, |
| - ERR_CONNECTION_CLOSED); |
| - set_stream(stream.Pass()); |
| - { |
| - InSequence s; |
| - EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| - EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| - EXPECT_CALL(*event_interface_, |
| - OnDropChannel(kWebSocketErrorAbnormalClosure, _)); |
| - } |
| - |
| - CreateChannelAndConnectSuccessfully(); |
| - base::MessageLoop::current()->RunUntilIdle(); |
| -} |
| - |
| // RFC6455 5.1 "A client MUST close a connection if it detects a masked frame." |
| TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 5}, FINAL_CHUNK, |
| - "HELLO"}}; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1276,10 +1088,9 @@ TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) { |
| TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, 4, NOT_MASKED, 5}, FINAL_CHUNK, "HELLO"}}; |
| + static const InitFrame frames[] = {{FINAL_FRAME, 4, NOT_MASKED, "HELLO"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1300,18 +1111,17 @@ TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) { |
| new ReadableFakeWebSocketStream); |
| // We have one message of type Text split into two frames. In the middle is a |
| // control message of type Pong. |
| - static const InitFrameChunk chunks1[] = { |
| - {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, 6}, |
| - FINAL_CHUNK, "SPLIT "}}; |
| - static const InitFrameChunk chunks2[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, 0}, |
| - FINAL_CHUNK, ""}}; |
| - static const InitFrameChunk chunks3[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, 7}, |
| - FINAL_CHUNK, "MESSAGE"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks1); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks2); |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks3); |
| + static const InitFrame frames1[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, |
| + NOT_MASKED, "SPLIT "}}; |
| + static const InitFrame frames2[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; |
| + static const InitFrame frames3[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + NOT_MASKED, "MESSAGE"}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1331,17 +1141,16 @@ TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) { |
| base::MessageLoop::current()->RunUntilIdle(); |
| } |
| -// If a chunk has an invalid header, then the connection is closed and |
| -// subsequent chunks must not trigger events. |
| -TEST_F(WebSocketChannelEventInterfaceTest, HeaderlessChunkAfterInvalidChunk) { |
| +// If a frame has an invalid header, then the connection is closed and |
| +// subsequent frames must not trigger events. |
| +TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 11}, |
| - NOT_FINAL_CHUNK, "HELLO"}, |
| - {{NO_HEADER}, FINAL_CHUNK, " WORLD"}}; |
| + static const InitFrame frames[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, " WORLD"}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, chunks); |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); |
| set_stream(stream.Pass()); |
| { |
| InSequence s; |
| @@ -1501,10 +1310,9 @@ TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) { |
| TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) { |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 0}, |
| - FINAL_CHUNK, ""}}; |
| - stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, chunks); |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; |
| + stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); |
| stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, |
| ERR_CONNECTION_CLOSED); |
| set_stream(stream.Pass()); |
| @@ -1521,12 +1329,12 @@ TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) { |
| // WebSocketChannel actually only sets the mask bit in the header, it doesn't |
| // perform masking itself (not all transports actually use masking). |
| TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 13}, |
| - FINAL_CHUNK, "NEEDS MASKING"}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, |
| + MASKED, "NEEDS MASKING"}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| CreateChannelAndConnectSuccessfully(); |
| @@ -1537,12 +1345,12 @@ TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { |
| // RFC6455 5.5.1 "The application MUST NOT send any more data frames after |
| // sending a Close frame." |
| TEST_F(WebSocketChannelStreamTest, NothingIsSentAfterClose) { |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 9}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| CreateChannelAndConnectSuccessfully(); |
| @@ -1554,17 +1362,17 @@ TEST_F(WebSocketChannelStreamTest, NothingIsSentAfterClose) { |
| // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously |
| // send a Close frame, the endpoint MUST send a Close frame in response." |
| TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 7}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| - .WillOnce(ReturnChunks(&chunks)) |
| + .WillOnce(ReturnFrames(&frames)) |
| .WillRepeatedly(Return(ERR_IO_PENDING)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| CreateChannelAndConnectSuccessfully(); |
| @@ -1573,17 +1381,17 @@ TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { |
| // The converse of the above case; after sending a Close frame, we should not |
| // send another one. |
| TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 7}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 7}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| + static const InitFrame frames_init[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; |
| // We store the parameters that were passed to ReadFrames() so that we can |
| // call them explicitly later. |
| CompletionCallback read_callback; |
| - ScopedVector<WebSocketFrameChunk>* frame_chunks = NULL; |
| + ScopedVector<WebSocketFrame>* frames = NULL; |
| // Use a checkpoint to make the ordering of events clearer. |
| MockFunction<void(int)> checkpoint; |
| @@ -1591,11 +1399,11 @@ TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { |
| InSequence s; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| - .WillOnce(DoAll(SaveArg<0>(&frame_chunks), |
| + .WillOnce(DoAll(SaveArg<0>(&frames), |
| SaveArg<1>(&read_callback), |
| Return(ERR_IO_PENDING))); |
| EXPECT_CALL(checkpoint, Call(1)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| EXPECT_CALL(checkpoint, Call(2)); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| @@ -1610,7 +1418,7 @@ TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { |
| channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close"); |
| checkpoint.Call(2); |
| - *frame_chunks = CreateFrameChunkVector(chunks); |
| + *frames = CreateFrameVector(frames_init); |
| read_callback.Run(OK); |
| checkpoint.Call(3); |
| } |
| @@ -1621,17 +1429,15 @@ TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { |
| // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is |
| // correctly generated internally. |
| TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 0}, |
| - FINAL_CHUNK, ""}}; |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 0}, |
| - FINAL_CHUNK, ""}}; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, ""}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| - .WillOnce(ReturnChunks(&chunks)) |
| + .WillOnce(ReturnFrames(&frames)) |
| .WillRepeatedly(Return(ERR_IO_PENDING)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| CreateChannelAndConnectSuccessfully(); |
| @@ -1643,58 +1449,57 @@ TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { |
| // "Application data" as found in the message body of the Ping frame being |
| // replied to." |
| TEST_F(WebSocketChannelStreamTest, PingRepliedWithPong) { |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 16}, |
| - FINAL_CHUNK, "Application data"}}; |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, MASKED, 16}, |
| - FINAL_CHUNK, "Application data"}}; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, |
| + NOT_MASKED, "Application data"}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, |
| + MASKED, "Application data"}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| - .WillOnce(ReturnChunks(&chunks)) |
| + .WillOnce(ReturnFrames(&frames)) |
| .WillRepeatedly(Return(ERR_IO_PENDING)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| CreateChannelAndConnectSuccessfully(); |
| } |
| TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) { |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 16}, |
| - FINAL_CHUNK, "Application data"}}; |
| - static const InitFrameChunk expected1[] = { |
| - {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 6}, |
| - FINAL_CHUNK, "Hello "}}; |
| - static const InitFrameChunk expected2[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, MASKED, 16}, |
| - FINAL_CHUNK, "Application data"}}; |
| - static const InitFrameChunk expected3[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, MASKED, 5}, |
| - FINAL_CHUNK, "World"}}; |
| - ScopedVector<WebSocketFrameChunk>* read_chunks; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, |
| + NOT_MASKED, "Application data"}}; |
| + static const InitFrame expected1[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; |
| + static const InitFrame expected2[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, |
| + MASKED, "Application data"}}; |
| + static const InitFrame expected3[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, |
| + MASKED, "World"}}; |
| + ScopedVector<WebSocketFrame>* read_frames; |
| CompletionCallback read_callback; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| - .WillOnce(DoAll(SaveArg<0>(&read_chunks), |
| + .WillOnce(DoAll(SaveArg<0>(&read_frames), |
| SaveArg<1>(&read_callback), |
| Return(ERR_IO_PENDING))) |
| .WillRepeatedly(Return(ERR_IO_PENDING)); |
| { |
| InSequence s; |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected1), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) |
| .WillOnce(Return(OK)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected2), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) |
| .WillOnce(Return(OK)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected3), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected3), _)) |
| .WillOnce(Return(OK)); |
| } |
| CreateChannelAndConnectSuccessfully(); |
| channel_->SendFrame( |
| false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); |
| - *read_chunks = CreateFrameChunkVector(chunks); |
| + *read_frames = CreateFrameVector(frames); |
| read_callback.Run(OK); |
| channel_->SendFrame( |
| true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("World")); |
| @@ -1703,12 +1508,10 @@ TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) { |
| // WriteFrames() may not be called until the previous write has completed. |
| // WebSocketChannel must buffer writes that happen in the meantime. |
| TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { |
| - static const InitFrameChunk expected1[] = { |
| - {{NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 6}, |
| - FINAL_CHUNK, "Hello "}}; |
| - static const InitFrameChunk expected2[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 5}, FINAL_CHUNK, |
| - "World"}}; |
| + static const InitFrame expected1[] = { |
| + {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; |
| + static const InitFrame expected2[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; |
| CompletionCallback write_callback; |
| MockFunction<void(int)> checkpoint; |
| @@ -1717,10 +1520,10 @@ TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { |
| { |
| InSequence s; |
| EXPECT_CALL(checkpoint, Call(1)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected1), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) |
| .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); |
| EXPECT_CALL(checkpoint, Call(2)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected2), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) |
| .WillOnce(Return(ERR_IO_PENDING)); |
| EXPECT_CALL(checkpoint, Call(3)); |
| } |
| @@ -1741,27 +1544,22 @@ TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { |
| // important to get good throughput in the "many small messages" case. |
| TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) { |
| static const char input_letters[] = "Hello"; |
| - static const InitFrameChunk expected1[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, |
| - "H"}}; |
| - static const InitFrameChunk expected2[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, |
| - "e"}, |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, |
| - "l"}, |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, |
| - "l"}, |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, 1}, FINAL_CHUNK, |
| - "o"}}; |
| + static const InitFrame expected1[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "H"}}; |
| + static const InitFrame expected2[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "e"}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "o"}}; |
| CompletionCallback write_callback; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| { |
| InSequence s; |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected1), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) |
| .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected2), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) |
| .WillOnce(Return(ERR_IO_PENDING)); |
| } |
| @@ -1781,12 +1579,12 @@ TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) { |
| // even be using a different extension which uses that code to mean something |
| // else. |
| TEST_F(WebSocketChannelStreamTest, MuxErrorIsNotSentToStream) { |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 16}, |
| - FINAL_CHUNK, CLOSE_DATA(GOING_AWAY, "Internal Error")}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + MASKED, CLOSE_DATA(GOING_AWAY, "Internal Error")}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| EXPECT_CALL(*mock_stream_, Close()); |
| @@ -1800,45 +1598,41 @@ TEST_F(WebSocketChannelStreamTest, MuxErrorIsNotSentToStream) { |
| // protocol also has Binary frames and those need to be 8-bit clean. For the |
| // sake of completeness, this test verifies that they are. |
| TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) { |
| - ScopedVector<WebSocketFrameChunk>* frame_chunks = NULL; |
| + ScopedVector<WebSocketFrame>* frames = NULL; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); |
| EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) |
| - .WillOnce(DoAll(SaveArg<0>(&frame_chunks), Return(ERR_IO_PENDING))); |
| + .WillOnce(DoAll(SaveArg<0>(&frames), Return(ERR_IO_PENDING))); |
| CreateChannelAndConnectSuccessfully(); |
| channel_->SendFrame( |
| true, |
| WebSocketFrameHeader::kOpCodeBinary, |
| std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize)); |
| - ASSERT_TRUE(frame_chunks != NULL); |
| - ASSERT_EQ(1U, frame_chunks->size()); |
| - const WebSocketFrameChunk* out_chunk = (*frame_chunks)[0]; |
| - ASSERT_TRUE(out_chunk->header); |
| - EXPECT_EQ(kBinaryBlobSize, out_chunk->header->payload_length); |
| - ASSERT_TRUE(out_chunk->data); |
| - EXPECT_EQ(kBinaryBlobSize, static_cast<size_t>(out_chunk->data->size())); |
| - EXPECT_EQ(0, memcmp(kBinaryBlob, out_chunk->data->data(), kBinaryBlobSize)); |
| + ASSERT_TRUE(frames != NULL); |
| + ASSERT_EQ(1U, frames->size()); |
| + const WebSocketFrame* out_frame = (*frames)[0]; |
| + EXPECT_EQ(kBinaryBlobSize, out_frame->header.payload_length); |
| + ASSERT_TRUE(out_frame->data); |
| + EXPECT_EQ(0, memcmp(kBinaryBlob, out_frame->data->data(), kBinaryBlobSize)); |
| } |
| // Test the read path for 8-bit cleanliness as well. |
| TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) { |
| - scoped_ptr<WebSocketFrameHeader> frame_header( |
| - new WebSocketFrameHeader(WebSocketFrameHeader::kOpCodeBinary)); |
| - frame_header->final = true; |
| - frame_header->payload_length = kBinaryBlobSize; |
| - scoped_ptr<WebSocketFrameChunk> frame_chunk(new WebSocketFrameChunk); |
| - frame_chunk->header = frame_header.Pass(); |
| - frame_chunk->final_chunk = true; |
| - frame_chunk->data = new IOBufferWithSize(kBinaryBlobSize); |
| - memcpy(frame_chunk->data->data(), kBinaryBlob, kBinaryBlobSize); |
| - ScopedVector<WebSocketFrameChunk> chunks; |
| - chunks.push_back(frame_chunk.release()); |
| + scoped_ptr<WebSocketFrame> frame( |
| + new WebSocketFrame(WebSocketFrameHeader::kOpCodeBinary)); |
| + WebSocketFrameHeader& frame_header = frame->header; |
| + frame_header.final = true; |
| + frame_header.payload_length = kBinaryBlobSize; |
| + frame->data = new IOBuffer(kBinaryBlobSize); |
| + memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize); |
| + ScopedVector<WebSocketFrame> frames; |
| + frames.push_back(frame.release()); |
| scoped_ptr<ReadableFakeWebSocketStream> stream( |
| new ReadableFakeWebSocketStream); |
| stream->PrepareRawReadFrames( |
| - ReadableFakeWebSocketStream::SYNC, OK, chunks.Pass()); |
| + ReadableFakeWebSocketStream::SYNC, OK, frames.Pass()); |
| set_stream(stream.Pass()); |
| EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); |
| EXPECT_CALL(*event_interface_, OnFlowControl(_)); |
| @@ -1856,17 +1650,17 @@ TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) { |
| // but the current implementation fails the connection. Since a Close has |
| // already been sent, this just means closing the connection. |
| TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { |
| - static const InitFrameChunk chunks[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 4}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, 9}, |
| - FINAL_CHUNK, "Ping body"}}; |
| - static const InitFrameChunk expected[] = { |
| - {{FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 4}, |
| - FINAL_CHUNK, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; |
| + static const InitFrame frames[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, |
| + NOT_MASKED, "Ping body"}}; |
| + static const InitFrame expected[] = { |
| + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, |
| + MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; |
| EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); |
| EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) |
| - .WillOnce(ReturnChunks(&chunks)) |
| + .WillOnce(ReturnFrames(&frames)) |
| .WillRepeatedly(Return(ERR_IO_PENDING)); |
| { |
| // We only need to verify the relative order of WriteFrames() and |
| @@ -1874,7 +1668,7 @@ TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { |
| // frame before calling ReadFrames() again, but that is an implementation |
| // detail and better not to consider required behaviour. |
| InSequence s; |
| - EXPECT_CALL(*mock_stream_, WriteFrames(EqualsChunks(expected), _)) |
| + EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) |
| .WillOnce(Return(OK)); |
| EXPECT_CALL(*mock_stream_, Close()).Times(1); |
| } |