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 |