| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/websockets/websocket_frame.h" | 5 #include "net/websockets/websocket_frame.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 { "\x81\x7D", 2, GG_UINT64_C(125) }, | 38 { "\x81\x7D", 2, GG_UINT64_C(125) }, |
| 39 { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126) }, | 39 { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126) }, |
| 40 { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF) }, | 40 { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF) }, |
| 41 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000) }, | 41 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000) }, |
| 42 { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10, | 42 { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10, |
| 43 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } | 43 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } |
| 44 }; | 44 }; |
| 45 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 45 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); |
| 46 | 46 |
| 47 for (int i = 0; i < kNumTests; ++i) { | 47 for (int i = 0; i < kNumTests; ++i) { |
| 48 WebSocketFrameHeader header; | 48 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 49 header.final = true; | 49 header.final = true; |
| 50 header.reserved1 = false; | |
| 51 header.reserved2 = false; | |
| 52 header.reserved3 = false; | |
| 53 header.opcode = WebSocketFrameHeader::kOpCodeText; | |
| 54 header.masked = false; | |
| 55 header.payload_length = kTests[i].frame_length; | 50 header.payload_length = kTests[i].frame_length; |
| 56 | 51 |
| 57 std::vector<char> expected_output( | 52 std::vector<char> expected_output( |
| 58 kTests[i].frame_header, | 53 kTests[i].frame_header, |
| 59 kTests[i].frame_header + kTests[i].frame_header_length); | 54 kTests[i].frame_header + kTests[i].frame_header_length); |
| 60 std::vector<char> output(expected_output.size()); | 55 std::vector<char> output(expected_output.size()); |
| 61 EXPECT_EQ(static_cast<int>(expected_output.size()), | 56 EXPECT_EQ(static_cast<int>(expected_output.size()), |
| 62 WriteWebSocketFrameHeader(header, NULL, &output.front(), | 57 WriteWebSocketFrameHeader(header, NULL, &output.front(), |
| 63 output.size())); | 58 output.size())); |
| 64 EXPECT_EQ(expected_output, output); | 59 EXPECT_EQ(expected_output, output); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 86 { "\x81\xFF\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDE\xAD\xBE\xEF", 14, | 81 { "\x81\xFF\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xDE\xAD\xBE\xEF", 14, |
| 87 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } | 82 GG_UINT64_C(0x7FFFFFFFFFFFFFFF) } |
| 88 }; | 83 }; |
| 89 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 84 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); |
| 90 | 85 |
| 91 WebSocketMaskingKey masking_key; | 86 WebSocketMaskingKey masking_key; |
| 92 std::copy(kMaskingKey, kMaskingKey + WebSocketFrameHeader::kMaskingKeyLength, | 87 std::copy(kMaskingKey, kMaskingKey + WebSocketFrameHeader::kMaskingKeyLength, |
| 93 masking_key.key); | 88 masking_key.key); |
| 94 | 89 |
| 95 for (int i = 0; i < kNumTests; ++i) { | 90 for (int i = 0; i < kNumTests; ++i) { |
| 96 WebSocketFrameHeader header; | 91 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 97 header.final = true; | 92 header.final = true; |
| 98 header.reserved1 = false; | |
| 99 header.reserved2 = false; | |
| 100 header.reserved3 = false; | |
| 101 header.opcode = WebSocketFrameHeader::kOpCodeText; | |
| 102 header.masked = true; | 93 header.masked = true; |
| 103 header.payload_length = kTests[i].frame_length; | 94 header.payload_length = kTests[i].frame_length; |
| 104 | 95 |
| 105 std::vector<char> expected_output( | 96 std::vector<char> expected_output( |
| 106 kTests[i].frame_header, | 97 kTests[i].frame_header, |
| 107 kTests[i].frame_header + kTests[i].frame_header_length); | 98 kTests[i].frame_header + kTests[i].frame_header_length); |
| 108 std::vector<char> output(expected_output.size()); | 99 std::vector<char> output(expected_output.size()); |
| 109 EXPECT_EQ(static_cast<int>(expected_output.size()), | 100 EXPECT_EQ(static_cast<int>(expected_output.size()), |
| 110 WriteWebSocketFrameHeader(header, &masking_key, | 101 WriteWebSocketFrameHeader(header, &masking_key, |
| 111 &output.front(), output.size())); | 102 &output.front(), output.size())); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 134 { "\x87\x00", 2, 0x7 }, | 125 { "\x87\x00", 2, 0x7 }, |
| 135 { "\x8B\x00", 2, 0xB }, | 126 { "\x8B\x00", 2, 0xB }, |
| 136 { "\x8C\x00", 2, 0xC }, | 127 { "\x8C\x00", 2, 0xC }, |
| 137 { "\x8D\x00", 2, 0xD }, | 128 { "\x8D\x00", 2, 0xD }, |
| 138 { "\x8E\x00", 2, 0xE }, | 129 { "\x8E\x00", 2, 0xE }, |
| 139 { "\x8F\x00", 2, 0xF } | 130 { "\x8F\x00", 2, 0xF } |
| 140 }; | 131 }; |
| 141 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 132 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); |
| 142 | 133 |
| 143 for (int i = 0; i < kNumTests; ++i) { | 134 for (int i = 0; i < kNumTests; ++i) { |
| 144 WebSocketFrameHeader header; | 135 WebSocketFrameHeader header(kTests[i].opcode); |
| 145 header.final = true; | 136 header.final = true; |
| 146 header.reserved1 = false; | |
| 147 header.reserved2 = false; | |
| 148 header.reserved3 = false; | |
| 149 header.opcode = kTests[i].opcode; | |
| 150 header.masked = false; | |
| 151 header.payload_length = 0; | 137 header.payload_length = 0; |
| 152 | 138 |
| 153 std::vector<char> expected_output( | 139 std::vector<char> expected_output( |
| 154 kTests[i].frame_header, | 140 kTests[i].frame_header, |
| 155 kTests[i].frame_header + kTests[i].frame_header_length); | 141 kTests[i].frame_header + kTests[i].frame_header_length); |
| 156 std::vector<char> output(expected_output.size()); | 142 std::vector<char> output(expected_output.size()); |
| 157 EXPECT_EQ(static_cast<int>(expected_output.size()), | 143 EXPECT_EQ(static_cast<int>(expected_output.size()), |
| 158 WriteWebSocketFrameHeader(header, NULL, | 144 WriteWebSocketFrameHeader(header, NULL, |
| 159 &output.front(), output.size())); | 145 &output.front(), output.size())); |
| 160 EXPECT_EQ(expected_output, output); | 146 EXPECT_EQ(expected_output, output); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 175 { "\x01\x00", 2, false, false, false, false }, | 161 { "\x01\x00", 2, false, false, false, false }, |
| 176 { "\xC1\x00", 2, true, true, false, false }, | 162 { "\xC1\x00", 2, true, true, false, false }, |
| 177 { "\xA1\x00", 2, true, false, true, false }, | 163 { "\xA1\x00", 2, true, false, true, false }, |
| 178 { "\x91\x00", 2, true, false, false, true }, | 164 { "\x91\x00", 2, true, false, false, true }, |
| 179 { "\x71\x00", 2, false, true, true, true }, | 165 { "\x71\x00", 2, false, true, true, true }, |
| 180 { "\xF1\x00", 2, true, true, true, true } | 166 { "\xF1\x00", 2, true, true, true, true } |
| 181 }; | 167 }; |
| 182 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 168 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); |
| 183 | 169 |
| 184 for (int i = 0; i < kNumTests; ++i) { | 170 for (int i = 0; i < kNumTests; ++i) { |
| 185 WebSocketFrameHeader header; | 171 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 186 header.final = kTests[i].final; | 172 header.final = kTests[i].final; |
| 187 header.reserved1 = kTests[i].reserved1; | 173 header.reserved1 = kTests[i].reserved1; |
| 188 header.reserved2 = kTests[i].reserved2; | 174 header.reserved2 = kTests[i].reserved2; |
| 189 header.reserved3 = kTests[i].reserved3; | 175 header.reserved3 = kTests[i].reserved3; |
| 190 header.opcode = WebSocketFrameHeader::kOpCodeText; | |
| 191 header.masked = false; | |
| 192 header.payload_length = 0; | 176 header.payload_length = 0; |
| 193 | 177 |
| 194 std::vector<char> expected_output( | 178 std::vector<char> expected_output( |
| 195 kTests[i].frame_header, | 179 kTests[i].frame_header, |
| 196 kTests[i].frame_header + kTests[i].frame_header_length); | 180 kTests[i].frame_header + kTests[i].frame_header_length); |
| 197 std::vector<char> output(expected_output.size()); | 181 std::vector<char> output(expected_output.size()); |
| 198 EXPECT_EQ(static_cast<int>(expected_output.size()), | 182 EXPECT_EQ(static_cast<int>(expected_output.size()), |
| 199 WriteWebSocketFrameHeader(header, NULL, | 183 WriteWebSocketFrameHeader(header, NULL, |
| 200 &output.front(), output.size())); | 184 &output.front(), output.size())); |
| 201 EXPECT_EQ(expected_output, output); | 185 EXPECT_EQ(expected_output, output); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 218 { GG_UINT64_C(0), true, 6u }, | 202 { GG_UINT64_C(0), true, 6u }, |
| 219 { GG_UINT64_C(125), true, 6u }, | 203 { GG_UINT64_C(125), true, 6u }, |
| 220 { GG_UINT64_C(126), true, 8u }, | 204 { GG_UINT64_C(126), true, 8u }, |
| 221 { GG_UINT64_C(0xFFFF), true, 8u }, | 205 { GG_UINT64_C(0xFFFF), true, 8u }, |
| 222 { GG_UINT64_C(0x10000), true, 14u }, | 206 { GG_UINT64_C(0x10000), true, 14u }, |
| 223 { GG_UINT64_C(0x7FFFFFFFFFFFFFFF), true, 14u } | 207 { GG_UINT64_C(0x7FFFFFFFFFFFFFFF), true, 14u } |
| 224 }; | 208 }; |
| 225 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); | 209 static const int kNumTests = ARRAYSIZE_UNSAFE(kTests); |
| 226 | 210 |
| 227 for (int i = 0; i < kNumTests; ++i) { | 211 for (int i = 0; i < kNumTests; ++i) { |
| 228 WebSocketFrameHeader header; | 212 WebSocketFrameHeader header(WebSocketFrameHeader::kOpCodeText); |
| 229 header.final = true; | 213 header.final = true; |
| 230 header.reserved1 = false; | |
| 231 header.reserved2 = false; | |
| 232 header.reserved3 = false; | |
| 233 header.opcode = WebSocketFrameHeader::kOpCodeText; | 214 header.opcode = WebSocketFrameHeader::kOpCodeText; |
| 234 header.masked = kTests[i].masked; | 215 header.masked = kTests[i].masked; |
| 235 header.payload_length = kTests[i].payload_length; | 216 header.payload_length = kTests[i].payload_length; |
| 236 | 217 |
| 237 char dummy_buffer[14]; | 218 char dummy_buffer[14]; |
| 238 // Set an insufficient size to |buffer_size|. | 219 // Set an insufficient size to |buffer_size|. |
| 239 EXPECT_EQ(ERR_INVALID_ARGUMENT, | 220 EXPECT_EQ(ERR_INVALID_ARGUMENT, |
| 240 WriteWebSocketFrameHeader(header, NULL, dummy_buffer, | 221 WriteWebSocketFrameHeader(header, NULL, dummy_buffer, |
| 241 kTests[i].expected_header_size - 1)); | 222 kTests[i].expected_header_size - 1)); |
| 242 } | 223 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 static const char kShortPayload[] = "Short Payload"; | 397 static const char kShortPayload[] = "Short Payload"; |
| 417 Benchmark(kShortPayload, arraysize(kShortPayload)); | 398 Benchmark(kShortPayload, arraysize(kShortPayload)); |
| 418 } | 399 } |
| 419 | 400 |
| 420 TEST_F(WebSocketFrameTestMaskBenchmark, BenchmarkMaskLongPayload) { | 401 TEST_F(WebSocketFrameTestMaskBenchmark, BenchmarkMaskLongPayload) { |
| 421 scoped_ptr<char[]> payload(new char[kLongPayloadSize]); | 402 scoped_ptr<char[]> payload(new char[kLongPayloadSize]); |
| 422 std::fill(payload.get(), payload.get() + kLongPayloadSize, 'a'); | 403 std::fill(payload.get(), payload.get() + kLongPayloadSize, 'a'); |
| 423 Benchmark(payload.get(), kLongPayloadSize); | 404 Benchmark(payload.get(), kLongPayloadSize); |
| 424 } | 405 } |
| 425 | 406 |
| 407 // "IsKnownDataOpCode" is implemented using bit-mangling for efficiency, so we |
| 408 // need to check that the results match the actual op-codes defined. |
| 409 TEST(WebSocketFrameHeaderTest, IsKnownDataOpCode) { |
| 410 // Make the test less verbose. |
| 411 typedef WebSocketFrameHeader Frame; |
| 412 |
| 413 // Known opcode, is used for data frames |
| 414 EXPECT_TRUE(Frame::IsKnownDataOpCode(Frame::kOpCodeContinuation)); |
| 415 EXPECT_TRUE(Frame::IsKnownDataOpCode(Frame::kOpCodeText)); |
| 416 EXPECT_TRUE(Frame::IsKnownDataOpCode(Frame::kOpCodeBinary)); |
| 417 |
| 418 // Known opcode, is used for control frames |
| 419 EXPECT_FALSE(Frame::IsKnownDataOpCode(Frame::kOpCodeClose)); |
| 420 EXPECT_FALSE(Frame::IsKnownDataOpCode(Frame::kOpCodePing)); |
| 421 EXPECT_FALSE(Frame::IsKnownDataOpCode(Frame::kOpCodePong)); |
| 422 |
| 423 // Check that unused opcodes return false |
| 424 EXPECT_FALSE(Frame::IsKnownDataOpCode(Frame::kOpCodeDataUnused)); |
| 425 EXPECT_FALSE(Frame::IsKnownDataOpCode(Frame::kOpCodeControlUnused)); |
| 426 |
| 427 // Check that opcodes with the 4 bit set return false |
| 428 EXPECT_FALSE(Frame::IsKnownDataOpCode(0x6)); |
| 429 EXPECT_FALSE(Frame::IsKnownDataOpCode(0xF)); |
| 430 |
| 431 // Check that out-of-range opcodes return false |
| 432 EXPECT_FALSE(Frame::IsKnownDataOpCode(-1)); |
| 433 EXPECT_FALSE(Frame::IsKnownDataOpCode(0xFF)); |
| 434 } |
| 435 |
| 436 // "IsKnownControlOpCode" is implemented using bit-mangling as with |
| 437 // "IsKnownDataOpCode". |
| 438 TEST(WebSocketFrameHeaderTest, IsKnownControlOpCode) { |
| 439 // Make the test less verbose. |
| 440 typedef WebSocketFrameHeader Frame; |
| 441 |
| 442 // Known opcode, is used for data frames |
| 443 EXPECT_FALSE(Frame::IsKnownControlOpCode(Frame::kOpCodeContinuation)); |
| 444 EXPECT_FALSE(Frame::IsKnownControlOpCode(Frame::kOpCodeText)); |
| 445 EXPECT_FALSE(Frame::IsKnownControlOpCode(Frame::kOpCodeBinary)); |
| 446 |
| 447 // Known opcode, is used for control frames |
| 448 EXPECT_TRUE(Frame::IsKnownControlOpCode(Frame::kOpCodeClose)); |
| 449 EXPECT_TRUE(Frame::IsKnownControlOpCode(Frame::kOpCodePing)); |
| 450 EXPECT_TRUE(Frame::IsKnownControlOpCode(Frame::kOpCodePong)); |
| 451 |
| 452 // Check that unused opcodes return false |
| 453 EXPECT_FALSE(Frame::IsKnownControlOpCode(Frame::kOpCodeDataUnused)); |
| 454 EXPECT_FALSE(Frame::IsKnownControlOpCode(Frame::kOpCodeControlUnused)); |
| 455 |
| 456 // Check that opcodes with the 4 bit set return false |
| 457 EXPECT_FALSE(Frame::IsKnownControlOpCode(0x6)); |
| 458 EXPECT_FALSE(Frame::IsKnownControlOpCode(0xF)); |
| 459 |
| 460 // Check that out-of-range opcodes return false |
| 461 EXPECT_FALSE(Frame::IsKnownControlOpCode(-1)); |
| 462 EXPECT_FALSE(Frame::IsKnownControlOpCode(0xFF)); |
| 463 } |
| 464 |
| 426 } // namespace net | 465 } // namespace net |
| OLD | NEW |