// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/websockets/websocket_frame_parser.h"

#include <algorithm>
#include <vector>

#include "base/basictypes.h"
#include "base/memory/scoped_vector.h"
#include "base/port.h"
#include "net/base/io_buffer.h"
#include "net/websockets/websocket_frame.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

const char kHello[] = "Hello, world!";
const uint64 kHelloLength = arraysize(kHello) - 1;
const char kHelloFrame[] = "\x81\x0DHello, world!";
const uint64 kHelloFrameLength = arraysize(kHelloFrame) - 1;
const char kMaskedHelloFrame[] =
    "\x81\x8D\xDE\xAD\xBE\xEF"
    "\x96\xC8\xD2\x83\xB1\x81\x9E\x98\xB1\xDF\xD2\x8B\xFF";
const uint64 kMaskedHelloFrameLength = arraysize(kMaskedHelloFrame) - 1;

struct FrameHeaderTestCase {
  const char* frame_header;
  size_t frame_header_length;
  uint64 frame_length;
  WebSocketError error_code;
};

const FrameHeaderTestCase kFrameHeaderTests[] = {
  { "\x81\x00", 2, GG_UINT64_C(0), WEB_SOCKET_OK },
  { "\x81\x7D", 2, GG_UINT64_C(125), WEB_SOCKET_OK },
  { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126), WEB_SOCKET_OK },
  { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF), WEB_SOCKET_OK },
  { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000),
    WEB_SOCKET_OK },
  { "\x81\x7F\x00\x00\x00\x00\x7F\xFF\xFF\xFF", 10, GG_UINT64_C(0x7FFFFFFF),
    WEB_SOCKET_OK },
  { "\x81\x7F\x00\x00\x00\x00\x80\x00\x00\x00", 10, GG_UINT64_C(0x80000000),
    WEB_SOCKET_ERR_MESSAGE_TOO_BIG },
  { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10,
    GG_UINT64_C(0x7FFFFFFFFFFFFFFF), WEB_SOCKET_ERR_MESSAGE_TOO_BIG }
};
const int kNumFrameHeaderTests = arraysize(kFrameHeaderTests);

TEST(WebSocketFrameParserTest, DecodeNormalFrame) {
  WebSocketFrameParser parser;

  ScopedVector<WebSocketFrameChunk> frames;
  EXPECT_TRUE(parser.Decode(kHelloFrame, kHelloFrameLength, &frames));
  EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
  ASSERT_EQ(1u, frames.size());
  WebSocketFrameChunk* frame = frames[0];
  ASSERT_TRUE(frame != NULL);
  const WebSocketFrameHeader* header = frame->header.get();
  EXPECT_TRUE(header != NULL);
  if (header) {
    EXPECT_TRUE(header->final);
    EXPECT_FALSE(header->reserved1);
    EXPECT_FALSE(header->reserved2);
    EXPECT_FALSE(header->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
    EXPECT_FALSE(header->masked);
    EXPECT_EQ(kHelloLength, header->payload_length);
  }
  EXPECT_TRUE(frame->final_chunk);

  ASSERT_EQ(static_cast<int>(kHelloLength), frame->data->size());
  EXPECT_TRUE(std::equal(kHello, kHello + kHelloLength, frame->data->data()));
}

TEST(WebSocketFrameParserTest, DecodeMaskedFrame) {
  WebSocketFrameParser parser;

  ScopedVector<WebSocketFrameChunk> frames;
  EXPECT_TRUE(parser.Decode(kMaskedHelloFrame, kMaskedHelloFrameLength,
                            &frames));
  EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
  ASSERT_EQ(1u, frames.size());
  WebSocketFrameChunk* frame = frames[0];
  ASSERT_TRUE(frame != NULL);
  const WebSocketFrameHeader* header = frame->header.get();
  EXPECT_TRUE(header != NULL);
  if (header) {
    EXPECT_TRUE(header->final);
    EXPECT_FALSE(header->reserved1);
    EXPECT_FALSE(header->reserved2);
    EXPECT_FALSE(header->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
    EXPECT_TRUE(header->masked);
    EXPECT_EQ(kHelloLength, header->payload_length);
  }
  EXPECT_TRUE(frame->final_chunk);

  ASSERT_EQ(static_cast<int>(kHelloLength), frame->data->size());
  EXPECT_TRUE(std::equal(kHello, kHello + kHelloLength, frame->data->data()));
}

TEST(WebSocketFrameParserTest, DecodeManyFrames) {
  struct Input {
    const char* frame;
    size_t frame_length;
    const char* expected_payload;
    size_t expected_payload_length;
  };
  static const Input kInputs[] = {
    // Each |frame| data is split into two string literals because C++ lexers
    // consume unlimited number of hex characters in a hex character escape
    // (e.g. "\x05F" is not treated as { '\x5', 'F', '\0' } but as
    // { '\x5F', '\0' }).
    { "\x81\x05" "First", 7, "First", 5 },
    { "\x81\x06" "Second", 8, "Second", 6 },
    { "\x81\x05" "Third", 7, "Third", 5 },
    { "\x81\x06" "Fourth", 8, "Fourth", 6 },
    { "\x81\x05" "Fifth", 7, "Fifth", 5 },
    { "\x81\x05" "Sixth", 7, "Sixth", 5 },
    { "\x81\x07" "Seventh", 9, "Seventh", 7 },
    { "\x81\x06" "Eighth", 8, "Eighth", 6 },
    { "\x81\x05" "Ninth", 7, "Ninth", 5 },
    { "\x81\x05" "Tenth", 7, "Tenth", 5 }
  };
  static const int kNumInputs = ARRAYSIZE_UNSAFE(kInputs);

  std::vector<char> input;
  // Concatenate all frames.
  for (int i = 0; i < kNumInputs; ++i) {
    input.insert(input.end(),
                 kInputs[i].frame,
                 kInputs[i].frame + kInputs[i].frame_length);
  }

  WebSocketFrameParser parser;

  ScopedVector<WebSocketFrameChunk> frames;
  EXPECT_TRUE(parser.Decode(&input.front(), input.size(), &frames));
  EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
  ASSERT_EQ(static_cast<size_t>(kNumInputs), frames.size());

  for (int i = 0; i < kNumInputs; ++i) {
    WebSocketFrameChunk* frame = frames[i];
    EXPECT_TRUE(frame != NULL);
    if (!frame)
      continue;
    EXPECT_TRUE(frame->final_chunk);
    ASSERT_EQ(kInputs[i].expected_payload_length,
              static_cast<uint64>(frame->data->size()));
    EXPECT_TRUE(std::equal(
        kInputs[i].expected_payload,
        kInputs[i].expected_payload + kInputs[i].expected_payload_length,
        frame->data->data()));

    const WebSocketFrameHeader* header = frame->header.get();
    EXPECT_TRUE(header != NULL);
    if (!header)
      continue;
    EXPECT_TRUE(header->final);
    EXPECT_FALSE(header->reserved1);
    EXPECT_FALSE(header->reserved2);
    EXPECT_FALSE(header->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
    EXPECT_FALSE(header->masked);
    EXPECT_EQ(kInputs[i].expected_payload_length, header->payload_length);
  }
}

TEST(WebSocketFrameParserTest, DecodePartialFrame) {
  static const size_t kFrameHeaderSize = 2;

  for (size_t cutting_pos = 0; cutting_pos < kHelloLength; ++cutting_pos) {
    std::vector<char> input1(kHelloFrame,
                             kHelloFrame + kFrameHeaderSize + cutting_pos);
    std::vector<char> input2(kHelloFrame + input1.size(),
                             kHelloFrame + kHelloFrameLength);

    std::vector<char> expected1(kHello, kHello + cutting_pos);
    std::vector<char> expected2(kHello + cutting_pos, kHello + kHelloLength);

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames1;
    EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_EQ(1u, frames1.size());
    if (frames1.size() != 1u)
      continue;
    WebSocketFrameChunk* frame1 = frames1[0];
    EXPECT_TRUE(frame1 != NULL);
    if (!frame1)
      continue;
    EXPECT_FALSE(frame1->final_chunk);
    if (expected1.size() == 0) {
      EXPECT_EQ(NULL, frame1->data.get());
    } else {
      ASSERT_EQ(cutting_pos, static_cast<size_t>(frame1->data->size()));
      EXPECT_TRUE(std::equal(expected1.begin(),
                             expected1.end(),
                             frame1->data->data()));
    }
    const WebSocketFrameHeader* header1 = frame1->header.get();
    EXPECT_TRUE(header1 != NULL);
    if (!header1)
      continue;
    EXPECT_TRUE(header1->final);
    EXPECT_FALSE(header1->reserved1);
    EXPECT_FALSE(header1->reserved2);
    EXPECT_FALSE(header1->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header1->opcode);
    EXPECT_FALSE(header1->masked);
    EXPECT_EQ(kHelloLength, header1->payload_length);

    ScopedVector<WebSocketFrameChunk> frames2;
    EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_EQ(1u, frames2.size());
    if (frames2.size() != 1u)
      continue;
    WebSocketFrameChunk* frame2 = frames2[0];
    EXPECT_TRUE(frame2 != NULL);
    if (!frame2)
      continue;
    EXPECT_TRUE(frame2->final_chunk);
    if (expected2.size() == 0) {
      EXPECT_EQ(NULL, frame2->data.get());
    } else {
      ASSERT_EQ(expected2.size(), static_cast<uint64>(frame2->data->size()));
      EXPECT_TRUE(std::equal(expected2.begin(),
                             expected2.end(),
                             frame2->data->data()));
    }
    const WebSocketFrameHeader* header2 = frame2->header.get();
    EXPECT_TRUE(header2 == NULL);
  }
}

TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) {
  static const size_t kFrameHeaderSize = 6;

  for (size_t cutting_pos = 0; cutting_pos < kHelloLength; ++cutting_pos) {
    std::vector<char> input1(
        kMaskedHelloFrame,
        kMaskedHelloFrame + kFrameHeaderSize + cutting_pos);
    std::vector<char> input2(kMaskedHelloFrame + input1.size(),
                             kMaskedHelloFrame + kMaskedHelloFrameLength);

    std::vector<char> expected1(kHello, kHello + cutting_pos);
    std::vector<char> expected2(kHello + cutting_pos, kHello + kHelloLength);

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames1;
    EXPECT_TRUE(parser.Decode(&input1.front(), input1.size(), &frames1));
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_EQ(1u, frames1.size());
    if (frames1.size() != 1u)
      continue;
    WebSocketFrameChunk* frame1 = frames1[0];
    EXPECT_TRUE(frame1 != NULL);
    if (!frame1)
      continue;
    EXPECT_FALSE(frame1->final_chunk);
    if (expected1.size() == 0) {
      EXPECT_EQ(NULL, frame1->data.get());
    } else {
      ASSERT_EQ(expected1.size(), static_cast<uint64>(frame1->data->size()));
      EXPECT_TRUE(std::equal(expected1.begin(),
                             expected1.end(),
                             frame1->data->data()));
    }
    const WebSocketFrameHeader* header1 = frame1->header.get();
    EXPECT_TRUE(header1 != NULL);
    if (!header1)
      continue;
    EXPECT_TRUE(header1->final);
    EXPECT_FALSE(header1->reserved1);
    EXPECT_FALSE(header1->reserved2);
    EXPECT_FALSE(header1->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header1->opcode);
    EXPECT_TRUE(header1->masked);
    EXPECT_EQ(kHelloLength, header1->payload_length);

    ScopedVector<WebSocketFrameChunk> frames2;
    EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2));
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_EQ(1u, frames2.size());
    if (frames2.size() != 1u)
      continue;
    WebSocketFrameChunk* frame2 = frames2[0];
    EXPECT_TRUE(frame2 != NULL);
    if (!frame2)
      continue;
    EXPECT_TRUE(frame2->final_chunk);
    if (expected2.size() == 0) {
      EXPECT_EQ(NULL, frame2->data.get());
    } else {
      ASSERT_EQ(expected2.size(), static_cast<uint64>(frame2->data->size()));
      EXPECT_TRUE(std::equal(expected2.begin(),
                             expected2.end(),
                             frame2->data->data()));
    }
    const WebSocketFrameHeader* header2 = frame2->header.get();
    EXPECT_TRUE(header2 == NULL);
  }
}

TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) {
  for (int i = 0; i < kNumFrameHeaderTests; ++i) {
    const char* frame_header = kFrameHeaderTests[i].frame_header;
    size_t frame_header_length = kFrameHeaderTests[i].frame_header_length;
    uint64 frame_length = kFrameHeaderTests[i].frame_length;

    std::vector<char> input(frame_header, frame_header + frame_header_length);
    // Limit the payload size not to flood the console on failure.
    static const uint64 kMaxPayloadSize = 200;
    uint64 input_payload_size = std::min(frame_length, kMaxPayloadSize);
    input.insert(input.end(), input_payload_size, 'a');

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames;
    EXPECT_EQ(kFrameHeaderTests[i].error_code == WEB_SOCKET_OK,
        parser.Decode(&input.front(), input.size(), &frames));
    EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error());
    if (kFrameHeaderTests[i].error_code != WEB_SOCKET_OK) {
      EXPECT_EQ(0u, frames.size());
    } else {
      EXPECT_EQ(1u, frames.size());
    }
    if (frames.size() != 1u)
      continue;
    WebSocketFrameChunk* frame = frames[0];
    EXPECT_TRUE(frame != NULL);
    if (!frame)
      continue;
    if (frame_length == input_payload_size) {
      EXPECT_TRUE(frame->final_chunk);
    } else {
      EXPECT_FALSE(frame->final_chunk);
    }
    std::vector<char> expected_payload(input_payload_size, 'a');
    if (expected_payload.size() == 0) {
      EXPECT_EQ(NULL, frame->data.get());
    } else {
      ASSERT_EQ(expected_payload.size(),
                static_cast<uint64>(frame->data->size()));
      EXPECT_TRUE(std::equal(
          expected_payload.begin(),
          expected_payload.end(),
          frame->data->data()));
    }
    const WebSocketFrameHeader* header = frame->header.get();
    EXPECT_TRUE(header != NULL);
    if (!header)
      continue;
    EXPECT_TRUE(header->final);
    EXPECT_FALSE(header->reserved1);
    EXPECT_FALSE(header->reserved2);
    EXPECT_FALSE(header->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
    EXPECT_FALSE(header->masked);
    EXPECT_EQ(frame_length, header->payload_length);
  }
}

TEST(WebSocketFrameParserTest, DecodePartialHeader) {
  for (int i = 0; i < kNumFrameHeaderTests; ++i) {
    const char* frame_header = kFrameHeaderTests[i].frame_header;
    size_t frame_header_length = kFrameHeaderTests[i].frame_header_length;
    uint64 frame_length = kFrameHeaderTests[i].frame_length;

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames;
    // Feed each byte to the parser to see if the parser behaves correctly
    // when it receives partial frame header.
    size_t last_byte_offset = frame_header_length - 1;
    for (size_t j = 0; j < frame_header_length; ++j) {
      bool failed = kFrameHeaderTests[i].error_code != WEB_SOCKET_OK &&
          j == last_byte_offset;
      EXPECT_EQ(!failed, parser.Decode(frame_header + j, 1, &frames));
      if (failed) {
        EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error());
      } else {
        EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
      }
      if (kFrameHeaderTests[i].error_code == WEB_SOCKET_OK &&
          j == last_byte_offset) {
        EXPECT_EQ(1u, frames.size());
      } else {
        EXPECT_EQ(0u, frames.size());
      }
    }
    if (frames.size() != 1u)
      continue;
    WebSocketFrameChunk* frame = frames[0];
    EXPECT_TRUE(frame != NULL);
    if (!frame)
      continue;
    if (frame_length == 0u) {
      EXPECT_TRUE(frame->final_chunk);
    } else {
      EXPECT_FALSE(frame->final_chunk);
    }
    EXPECT_EQ(NULL, frame->data.get());
    const WebSocketFrameHeader* header = frame->header.get();
    EXPECT_TRUE(header != NULL);
    if (!header)
      continue;
    EXPECT_TRUE(header->final);
    EXPECT_FALSE(header->reserved1);
    EXPECT_FALSE(header->reserved2);
    EXPECT_FALSE(header->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
    EXPECT_FALSE(header->masked);
    EXPECT_EQ(frame_length, header->payload_length);
  }
}

TEST(WebSocketFrameParserTest, InvalidLengthEncoding) {
  struct TestCase {
    const char* frame_header;
    size_t frame_header_length;
  };
  static const TestCase kTests[] = {
    // For frames with two-byte extended length field, the payload length
    // should be 126 (0x7E) bytes or more.
    { "\x81\x7E\x00\x00", 4 },
    { "\x81\x7E\x00\x7D", 4 },
    // For frames with eight-byte extended length field, the payload length
    // should be 0x10000 bytes or more.
    { "\x81\x7F\x00\x00\x00\x00\x00\x00\x00\x00", 10 },
    { "\x81\x7E\x00\x00\x00\x00\x00\x00\xFF\xFF", 10 },
  };
  static const int kNumTests = ARRAYSIZE_UNSAFE(kTests);

  for (int i = 0; i < kNumTests; ++i) {
    const char* frame_header = kTests[i].frame_header;
    size_t frame_header_length = kTests[i].frame_header_length;

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames;
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_FALSE(parser.Decode(frame_header, frame_header_length, &frames));
    EXPECT_EQ(WEB_SOCKET_ERR_PROTOCOL_ERROR, parser.websocket_error());
    EXPECT_EQ(0u, frames.size());

    // Once the parser has failed, it no longer accepts any input (even if
    // the input is empty).
    EXPECT_FALSE(parser.Decode("", 0, &frames));
    EXPECT_EQ(WEB_SOCKET_ERR_PROTOCOL_ERROR, parser.websocket_error());
    EXPECT_EQ(0u, frames.size());
  }
}

TEST(WebSocketFrameParserTest, FrameTypes) {
  struct TestCase {
    const char* frame_header;
    size_t frame_header_length;
    WebSocketFrameHeader::OpCode opcode;
  };
  static const TestCase kTests[] = {
    { "\x80\x00", 2, WebSocketFrameHeader::kOpCodeContinuation },
    { "\x81\x00", 2, WebSocketFrameHeader::kOpCodeText },
    { "\x82\x00", 2, WebSocketFrameHeader::kOpCodeBinary },
    { "\x88\x00", 2, WebSocketFrameHeader::kOpCodeClose },
    { "\x89\x00", 2, WebSocketFrameHeader::kOpCodePing },
    { "\x8A\x00", 2, WebSocketFrameHeader::kOpCodePong },
    // These are undefined opcodes, but the parser needs to be able to parse
    // them anyway.
    { "\x83\x00", 2, 0x3 },
    { "\x84\x00", 2, 0x4 },
    { "\x85\x00", 2, 0x5 },
    { "\x86\x00", 2, 0x6 },
    { "\x87\x00", 2, 0x7 },
    { "\x8B\x00", 2, 0xB },
    { "\x8C\x00", 2, 0xC },
    { "\x8D\x00", 2, 0xD },
    { "\x8E\x00", 2, 0xE },
    { "\x8F\x00", 2, 0xF }
  };
  static const int kNumTests = ARRAYSIZE_UNSAFE(kTests);

  for (int i = 0; i < kNumTests; ++i) {
    const char* frame_header = kTests[i].frame_header;
    size_t frame_header_length = kTests[i].frame_header_length;
    WebSocketFrameHeader::OpCode opcode = kTests[i].opcode;

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames;
    EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_EQ(1u, frames.size());
    if (frames.size() != 1u)
      continue;
    WebSocketFrameChunk* frame = frames[0];
    EXPECT_TRUE(frame != NULL);
    if (!frame)
      continue;
    EXPECT_TRUE(frame->final_chunk);
    EXPECT_EQ(NULL, frame->data.get());
    const WebSocketFrameHeader* header = frame->header.get();
    EXPECT_TRUE(header != NULL);
    if (!header)
      continue;
    EXPECT_TRUE(header->final);
    EXPECT_FALSE(header->reserved1);
    EXPECT_FALSE(header->reserved2);
    EXPECT_FALSE(header->reserved3);
    EXPECT_EQ(opcode, header->opcode);
    EXPECT_FALSE(header->masked);
    EXPECT_EQ(0u, header->payload_length);
  }
}

TEST(WebSocketFrameParserTest, FinalBitAndReservedBits) {
  struct TestCase {
    const char* frame_header;
    size_t frame_header_length;
    bool final;
    bool reserved1;
    bool reserved2;
    bool reserved3;
  };
  static const TestCase kTests[] = {
    { "\x81\x00", 2, true, false, false, false },
    { "\x01\x00", 2, false, false, false, false },
    { "\xC1\x00", 2, true, true, false, false },
    { "\xA1\x00", 2, true, false, true, false },
    { "\x91\x00", 2, true, false, false, true },
    { "\x71\x00", 2, false, true, true, true },
    { "\xF1\x00", 2, true, true, true, true }
  };
  static const int kNumTests = ARRAYSIZE_UNSAFE(kTests);

  for (int i = 0; i < kNumTests; ++i) {
    const char* frame_header = kTests[i].frame_header;
    size_t frame_header_length = kTests[i].frame_header_length;
    bool final = kTests[i].final;
    bool reserved1 = kTests[i].reserved1;
    bool reserved2 = kTests[i].reserved2;
    bool reserved3 = kTests[i].reserved3;

    WebSocketFrameParser parser;

    ScopedVector<WebSocketFrameChunk> frames;
    EXPECT_TRUE(parser.Decode(frame_header, frame_header_length, &frames));
    EXPECT_EQ(WEB_SOCKET_OK, parser.websocket_error());
    EXPECT_EQ(1u, frames.size());
    if (frames.size() != 1u)
      continue;
    WebSocketFrameChunk* frame = frames[0];
    EXPECT_TRUE(frame != NULL);
    if (!frame)
      continue;
    EXPECT_TRUE(frame->final_chunk);
    EXPECT_EQ(NULL, frame->data.get());
    const WebSocketFrameHeader* header = frame->header.get();
    EXPECT_TRUE(header != NULL);
    if (!header)
      continue;
    EXPECT_EQ(final, header->final);
    EXPECT_EQ(reserved1, header->reserved1);
    EXPECT_EQ(reserved2, header->reserved2);
    EXPECT_EQ(reserved3, header->reserved3);
    EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode);
    EXPECT_FALSE(header->masked);
    EXPECT_EQ(0u, header->payload_length);
  }
}

}  // Unnamed namespace

}  // namespace net
