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