Retain empty first frames as well as final frames.

If the payload of the first frame of a multi-frame message was empty, then the
type of the message would be lost. To avoid this, always retain the first chunk
of the first frame of a message, even if the payload is empty.

Also add tests for empty frames, a frame larger than the read buffer,
and a masked frame with a non-nul mask.

Changed some ASSERT_EQ() statements that weren't necessary to prevent
tests from crashing or hanging into EXPECT_EQ() statements.

BUG=305081

Review URL: https://codereview.chromium.org/26440002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228161 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/websockets/websocket_basic_stream.cc b/net/websockets/websocket_basic_stream.cc
index f5d9a76..d3b1c40 100644
--- a/net/websockets/websocket_basic_stream.cc
+++ b/net/websockets/websocket_basic_stream.cc
@@ -379,9 +379,11 @@
       is_final_chunk && current_frame_header_->final;
   const int data_size = data ? data->size() : 0;
   const WebSocketFrameHeader::OpCode opcode = current_frame_header_->opcode;
-  // Empty frames convey no useful information unless they have the "final" bit
-  // set.
-  if (is_final_chunk_in_message || data_size > 0) {
+  // Empty frames convey no useful information unless they are the first frame
+  // (containing the type and flags) or have the "final" bit set.
+  if (is_final_chunk_in_message || data_size > 0 ||
+      current_frame_header_->opcode !=
+          WebSocketFrameHeader::kOpCodeContinuation) {
     result_frame.reset(new WebSocketFrame(opcode));
     result_frame->header.CopyFrom(*current_frame_header_);
     result_frame->header.final = is_final_chunk_in_message;