// Copyright 2013 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), kWebSocketNormalClosure },
  { "\x81\x7D", 2, GG_UINT64_C(125), kWebSocketNormalClosure },
  { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126), kWebSocketNormalClosure },
  { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF), kWebSocketNormalClosure },
  { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000),
    kWebSocketNormalClosure },
  { "\x81\x7F\x00\x00\x00\x00\x7F\xFF\xFF\xFF", 10, GG_UINT64_C(0x7FFFFFFF),
    kWebSocketNormalClosure },
  { "\x81\x7F\x00\x00\x00\x00\x80\x00\x00\x00", 10, GG_UINT64_C(0x80000000),
    kWebSocketErrorMessageTooBig },
  { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10,
    GG_UINT64_C(0x7FFFFFFFFFFFFFFF), kWebSocketErrorMessageTooBig }
};
const int kNumFrameHeaderTests = arraysize(kFrameHeaderTests);

TEST(WebSocketFrameParserTest, DecodeNormalFrame) {
  WebSocketFrameParser parser;

  ScopedVector<WebSocketFrameChunk> frames;
  EXPECT_TRUE(parser.Decode(kHelloFrame, kHelloFrameLength, &frames));
  EXPECT_EQ(kWebSocketNormalClosure, 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(kWebSocketNormalClosure, 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(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(kWebSocketNormalClosure, 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(kWebSocketNormalClosure, 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(kWebSocketNormalClosure, 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(kWebSocketNormalClosure, 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(kWebSocketNormalClosure, 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 == kWebSocketNormalClosure,
              parser.Decode(&input.front(), input.size(), &frames));
    EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error());
    if (kFrameHeaderTests[i].error_code != kWebSocketNormalClosure) {
      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 != kWebSocketNormalClosure &&
          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(kWebSocketNormalClosure, parser.websocket_error());
      }
      if (kFrameHeaderTests[i].error_code == kWebSocketNormalClosure &&
          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(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(kWebSocketNormalClosure, parser.websocket_error());
    EXPECT_FALSE(parser.Decode(frame_header, frame_header_length, &frames));
    EXPECT_EQ(kWebSocketErrorProtocolError, 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(kWebSocketErrorProtocolError, 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(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(kWebSocketNormalClosure, 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(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(kWebSocketNormalClosure, 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
