OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_parser.h" | 5 #include "net/websockets/websocket_frame_parser.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
13 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
14 #include "net/websockets/websocket_frame.h" | 14 #include "net/websockets/websocket_frame.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 namespace net { | 17 namespace net { |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 const char kHello[] = "Hello, world!"; | 21 const char kHello[] = "Hello, world!"; |
22 const uint64 kHelloLength = arraysize(kHello) - 1; | 22 const uint64_t kHelloLength = arraysize(kHello) - 1; |
23 const char kHelloFrame[] = "\x81\x0DHello, world!"; | 23 const char kHelloFrame[] = "\x81\x0DHello, world!"; |
24 const uint64 kHelloFrameLength = arraysize(kHelloFrame) - 1; | 24 const uint64_t kHelloFrameLength = arraysize(kHelloFrame) - 1; |
25 const char kMaskedHelloFrame[] = | 25 const char kMaskedHelloFrame[] = |
26 "\x81\x8D\xDE\xAD\xBE\xEF" | 26 "\x81\x8D\xDE\xAD\xBE\xEF" |
27 "\x96\xC8\xD2\x83\xB1\x81\x9E\x98\xB1\xDF\xD2\x8B\xFF"; | 27 "\x96\xC8\xD2\x83\xB1\x81\x9E\x98\xB1\xDF\xD2\x8B\xFF"; |
28 const uint64 kMaskedHelloFrameLength = arraysize(kMaskedHelloFrame) - 1; | 28 const uint64_t kMaskedHelloFrameLength = arraysize(kMaskedHelloFrame) - 1; |
29 | 29 |
30 struct FrameHeaderTestCase { | 30 struct FrameHeaderTestCase { |
31 const char* frame_header; | 31 const char* frame_header; |
32 size_t frame_header_length; | 32 size_t frame_header_length; |
33 uint64 frame_length; | 33 uint64_t frame_length; |
34 WebSocketError error_code; | 34 WebSocketError error_code; |
35 }; | 35 }; |
36 | 36 |
37 const FrameHeaderTestCase kFrameHeaderTests[] = { | 37 const FrameHeaderTestCase kFrameHeaderTests[] = { |
38 { "\x81\x00", 2, UINT64_C(0), kWebSocketNormalClosure }, | 38 { "\x81\x00", 2, UINT64_C(0), kWebSocketNormalClosure }, |
39 { "\x81\x7D", 2, UINT64_C(125), kWebSocketNormalClosure }, | 39 { "\x81\x7D", 2, UINT64_C(125), kWebSocketNormalClosure }, |
40 { "\x81\x7E\x00\x7E", 4, UINT64_C(126), kWebSocketNormalClosure }, | 40 { "\x81\x7E\x00\x7E", 4, UINT64_C(126), kWebSocketNormalClosure }, |
41 { "\x81\x7E\xFF\xFF", 4, UINT64_C(0xFFFF), kWebSocketNormalClosure }, | 41 { "\x81\x7E\xFF\xFF", 4, UINT64_C(0xFFFF), kWebSocketNormalClosure }, |
42 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, UINT64_C(0x10000), | 42 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, UINT64_C(0x10000), |
43 kWebSocketNormalClosure }, | 43 kWebSocketNormalClosure }, |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error()); | 143 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error()); |
144 ASSERT_EQ(static_cast<size_t>(kNumInputs), frames.size()); | 144 ASSERT_EQ(static_cast<size_t>(kNumInputs), frames.size()); |
145 | 145 |
146 for (int i = 0; i < kNumInputs; ++i) { | 146 for (int i = 0; i < kNumInputs; ++i) { |
147 WebSocketFrameChunk* frame = frames[i]; | 147 WebSocketFrameChunk* frame = frames[i]; |
148 EXPECT_TRUE(frame != NULL); | 148 EXPECT_TRUE(frame != NULL); |
149 if (!frame) | 149 if (!frame) |
150 continue; | 150 continue; |
151 EXPECT_TRUE(frame->final_chunk); | 151 EXPECT_TRUE(frame->final_chunk); |
152 ASSERT_EQ(kInputs[i].expected_payload_length, | 152 ASSERT_EQ(kInputs[i].expected_payload_length, |
153 static_cast<uint64>(frame->data->size())); | 153 static_cast<uint64_t>(frame->data->size())); |
154 EXPECT_TRUE(std::equal( | 154 EXPECT_TRUE(std::equal( |
155 kInputs[i].expected_payload, | 155 kInputs[i].expected_payload, |
156 kInputs[i].expected_payload + kInputs[i].expected_payload_length, | 156 kInputs[i].expected_payload + kInputs[i].expected_payload_length, |
157 frame->data->data())); | 157 frame->data->data())); |
158 | 158 |
159 const WebSocketFrameHeader* header = frame->header.get(); | 159 const WebSocketFrameHeader* header = frame->header.get(); |
160 EXPECT_TRUE(header != NULL); | 160 EXPECT_TRUE(header != NULL); |
161 if (!header) | 161 if (!header) |
162 continue; | 162 continue; |
163 EXPECT_TRUE(header->final); | 163 EXPECT_TRUE(header->final); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 if (frames2.size() != 1u) | 221 if (frames2.size() != 1u) |
222 continue; | 222 continue; |
223 WebSocketFrameChunk* frame2 = frames2[0]; | 223 WebSocketFrameChunk* frame2 = frames2[0]; |
224 EXPECT_TRUE(frame2 != NULL); | 224 EXPECT_TRUE(frame2 != NULL); |
225 if (!frame2) | 225 if (!frame2) |
226 continue; | 226 continue; |
227 EXPECT_TRUE(frame2->final_chunk); | 227 EXPECT_TRUE(frame2->final_chunk); |
228 if (expected2.size() == 0) { | 228 if (expected2.size() == 0) { |
229 EXPECT_EQ(NULL, frame2->data.get()); | 229 EXPECT_EQ(NULL, frame2->data.get()); |
230 } else { | 230 } else { |
231 ASSERT_EQ(expected2.size(), static_cast<uint64>(frame2->data->size())); | 231 ASSERT_EQ(expected2.size(), static_cast<uint64_t>(frame2->data->size())); |
232 EXPECT_TRUE( | 232 EXPECT_TRUE( |
233 std::equal(expected2.begin(), expected2.end(), frame2->data->data())); | 233 std::equal(expected2.begin(), expected2.end(), frame2->data->data())); |
234 } | 234 } |
235 const WebSocketFrameHeader* header2 = frame2->header.get(); | 235 const WebSocketFrameHeader* header2 = frame2->header.get(); |
236 EXPECT_TRUE(header2 == NULL); | 236 EXPECT_TRUE(header2 == NULL); |
237 } | 237 } |
238 } | 238 } |
239 | 239 |
240 TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) { | 240 TEST(WebSocketFrameParserTest, DecodePartialMaskedFrame) { |
241 static const size_t kFrameHeaderSize = 6; | 241 static const size_t kFrameHeaderSize = 6; |
(...skipping 16 matching lines...) Expand all Loading... |
258 if (frames1.size() != 1u) | 258 if (frames1.size() != 1u) |
259 continue; | 259 continue; |
260 WebSocketFrameChunk* frame1 = frames1[0]; | 260 WebSocketFrameChunk* frame1 = frames1[0]; |
261 EXPECT_TRUE(frame1 != NULL); | 261 EXPECT_TRUE(frame1 != NULL); |
262 if (!frame1) | 262 if (!frame1) |
263 continue; | 263 continue; |
264 EXPECT_FALSE(frame1->final_chunk); | 264 EXPECT_FALSE(frame1->final_chunk); |
265 if (expected1.size() == 0) { | 265 if (expected1.size() == 0) { |
266 EXPECT_EQ(NULL, frame1->data.get()); | 266 EXPECT_EQ(NULL, frame1->data.get()); |
267 } else { | 267 } else { |
268 ASSERT_EQ(expected1.size(), static_cast<uint64>(frame1->data->size())); | 268 ASSERT_EQ(expected1.size(), static_cast<uint64_t>(frame1->data->size())); |
269 EXPECT_TRUE( | 269 EXPECT_TRUE( |
270 std::equal(expected1.begin(), expected1.end(), frame1->data->data())); | 270 std::equal(expected1.begin(), expected1.end(), frame1->data->data())); |
271 } | 271 } |
272 const WebSocketFrameHeader* header1 = frame1->header.get(); | 272 const WebSocketFrameHeader* header1 = frame1->header.get(); |
273 EXPECT_TRUE(header1 != NULL); | 273 EXPECT_TRUE(header1 != NULL); |
274 if (!header1) | 274 if (!header1) |
275 continue; | 275 continue; |
276 EXPECT_TRUE(header1->final); | 276 EXPECT_TRUE(header1->final); |
277 EXPECT_FALSE(header1->reserved1); | 277 EXPECT_FALSE(header1->reserved1); |
278 EXPECT_FALSE(header1->reserved2); | 278 EXPECT_FALSE(header1->reserved2); |
279 EXPECT_FALSE(header1->reserved3); | 279 EXPECT_FALSE(header1->reserved3); |
280 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header1->opcode); | 280 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header1->opcode); |
281 EXPECT_TRUE(header1->masked); | 281 EXPECT_TRUE(header1->masked); |
282 EXPECT_EQ(kHelloLength, header1->payload_length); | 282 EXPECT_EQ(kHelloLength, header1->payload_length); |
283 | 283 |
284 ScopedVector<WebSocketFrameChunk> frames2; | 284 ScopedVector<WebSocketFrameChunk> frames2; |
285 EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2)); | 285 EXPECT_TRUE(parser.Decode(&input2.front(), input2.size(), &frames2)); |
286 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error()); | 286 EXPECT_EQ(kWebSocketNormalClosure, parser.websocket_error()); |
287 EXPECT_EQ(1u, frames2.size()); | 287 EXPECT_EQ(1u, frames2.size()); |
288 if (frames2.size() != 1u) | 288 if (frames2.size() != 1u) |
289 continue; | 289 continue; |
290 WebSocketFrameChunk* frame2 = frames2[0]; | 290 WebSocketFrameChunk* frame2 = frames2[0]; |
291 EXPECT_TRUE(frame2 != NULL); | 291 EXPECT_TRUE(frame2 != NULL); |
292 if (!frame2) | 292 if (!frame2) |
293 continue; | 293 continue; |
294 EXPECT_TRUE(frame2->final_chunk); | 294 EXPECT_TRUE(frame2->final_chunk); |
295 if (expected2.size() == 0) { | 295 if (expected2.size() == 0) { |
296 EXPECT_EQ(NULL, frame2->data.get()); | 296 EXPECT_EQ(NULL, frame2->data.get()); |
297 } else { | 297 } else { |
298 ASSERT_EQ(expected2.size(), static_cast<uint64>(frame2->data->size())); | 298 ASSERT_EQ(expected2.size(), static_cast<uint64_t>(frame2->data->size())); |
299 EXPECT_TRUE( | 299 EXPECT_TRUE( |
300 std::equal(expected2.begin(), expected2.end(), frame2->data->data())); | 300 std::equal(expected2.begin(), expected2.end(), frame2->data->data())); |
301 } | 301 } |
302 const WebSocketFrameHeader* header2 = frame2->header.get(); | 302 const WebSocketFrameHeader* header2 = frame2->header.get(); |
303 EXPECT_TRUE(header2 == NULL); | 303 EXPECT_TRUE(header2 == NULL); |
304 } | 304 } |
305 } | 305 } |
306 | 306 |
307 TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) { | 307 TEST(WebSocketFrameParserTest, DecodeFramesOfVariousLengths) { |
308 for (int i = 0; i < kNumFrameHeaderTests; ++i) { | 308 for (int i = 0; i < kNumFrameHeaderTests; ++i) { |
309 const char* frame_header = kFrameHeaderTests[i].frame_header; | 309 const char* frame_header = kFrameHeaderTests[i].frame_header; |
310 size_t frame_header_length = kFrameHeaderTests[i].frame_header_length; | 310 size_t frame_header_length = kFrameHeaderTests[i].frame_header_length; |
311 uint64 frame_length = kFrameHeaderTests[i].frame_length; | 311 uint64_t frame_length = kFrameHeaderTests[i].frame_length; |
312 | 312 |
313 std::vector<char> input(frame_header, frame_header + frame_header_length); | 313 std::vector<char> input(frame_header, frame_header + frame_header_length); |
314 // Limit the payload size not to flood the console on failure. | 314 // Limit the payload size not to flood the console on failure. |
315 static const uint64 kMaxPayloadSize = 200; | 315 static const uint64_t kMaxPayloadSize = 200; |
316 uint64 input_payload_size = std::min(frame_length, kMaxPayloadSize); | 316 uint64_t input_payload_size = std::min(frame_length, kMaxPayloadSize); |
317 input.insert(input.end(), input_payload_size, 'a'); | 317 input.insert(input.end(), input_payload_size, 'a'); |
318 | 318 |
319 WebSocketFrameParser parser; | 319 WebSocketFrameParser parser; |
320 | 320 |
321 ScopedVector<WebSocketFrameChunk> frames; | 321 ScopedVector<WebSocketFrameChunk> frames; |
322 EXPECT_EQ(kFrameHeaderTests[i].error_code == kWebSocketNormalClosure, | 322 EXPECT_EQ(kFrameHeaderTests[i].error_code == kWebSocketNormalClosure, |
323 parser.Decode(&input.front(), input.size(), &frames)); | 323 parser.Decode(&input.front(), input.size(), &frames)); |
324 EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error()); | 324 EXPECT_EQ(kFrameHeaderTests[i].error_code, parser.websocket_error()); |
325 if (kFrameHeaderTests[i].error_code != kWebSocketNormalClosure) { | 325 if (kFrameHeaderTests[i].error_code != kWebSocketNormalClosure) { |
326 EXPECT_EQ(0u, frames.size()); | 326 EXPECT_EQ(0u, frames.size()); |
327 } else { | 327 } else { |
328 EXPECT_EQ(1u, frames.size()); | 328 EXPECT_EQ(1u, frames.size()); |
329 } | 329 } |
330 if (frames.size() != 1u) | 330 if (frames.size() != 1u) |
331 continue; | 331 continue; |
332 WebSocketFrameChunk* frame = frames[0]; | 332 WebSocketFrameChunk* frame = frames[0]; |
333 EXPECT_TRUE(frame != NULL); | 333 EXPECT_TRUE(frame != NULL); |
334 if (!frame) | 334 if (!frame) |
335 continue; | 335 continue; |
336 if (frame_length == input_payload_size) { | 336 if (frame_length == input_payload_size) { |
337 EXPECT_TRUE(frame->final_chunk); | 337 EXPECT_TRUE(frame->final_chunk); |
338 } else { | 338 } else { |
339 EXPECT_FALSE(frame->final_chunk); | 339 EXPECT_FALSE(frame->final_chunk); |
340 } | 340 } |
341 std::vector<char> expected_payload(input_payload_size, 'a'); | 341 std::vector<char> expected_payload(input_payload_size, 'a'); |
342 if (expected_payload.size() == 0) { | 342 if (expected_payload.size() == 0) { |
343 EXPECT_EQ(NULL, frame->data.get()); | 343 EXPECT_EQ(NULL, frame->data.get()); |
344 } else { | 344 } else { |
345 ASSERT_EQ(expected_payload.size(), | 345 ASSERT_EQ(expected_payload.size(), |
346 static_cast<uint64>(frame->data->size())); | 346 static_cast<uint64_t>(frame->data->size())); |
347 EXPECT_TRUE(std::equal(expected_payload.begin(), | 347 EXPECT_TRUE(std::equal(expected_payload.begin(), |
348 expected_payload.end(), | 348 expected_payload.end(), |
349 frame->data->data())); | 349 frame->data->data())); |
350 } | 350 } |
351 const WebSocketFrameHeader* header = frame->header.get(); | 351 const WebSocketFrameHeader* header = frame->header.get(); |
352 EXPECT_TRUE(header != NULL); | 352 EXPECT_TRUE(header != NULL); |
353 if (!header) | 353 if (!header) |
354 continue; | 354 continue; |
355 EXPECT_TRUE(header->final); | 355 EXPECT_TRUE(header->final); |
356 EXPECT_FALSE(header->reserved1); | 356 EXPECT_FALSE(header->reserved1); |
357 EXPECT_FALSE(header->reserved2); | 357 EXPECT_FALSE(header->reserved2); |
358 EXPECT_FALSE(header->reserved3); | 358 EXPECT_FALSE(header->reserved3); |
359 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode); | 359 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode); |
360 EXPECT_FALSE(header->masked); | 360 EXPECT_FALSE(header->masked); |
361 EXPECT_EQ(frame_length, header->payload_length); | 361 EXPECT_EQ(frame_length, header->payload_length); |
362 } | 362 } |
363 } | 363 } |
364 | 364 |
365 TEST(WebSocketFrameParserTest, DecodePartialHeader) { | 365 TEST(WebSocketFrameParserTest, DecodePartialHeader) { |
366 for (int i = 0; i < kNumFrameHeaderTests; ++i) { | 366 for (int i = 0; i < kNumFrameHeaderTests; ++i) { |
367 const char* frame_header = kFrameHeaderTests[i].frame_header; | 367 const char* frame_header = kFrameHeaderTests[i].frame_header; |
368 size_t frame_header_length = kFrameHeaderTests[i].frame_header_length; | 368 size_t frame_header_length = kFrameHeaderTests[i].frame_header_length; |
369 uint64 frame_length = kFrameHeaderTests[i].frame_length; | 369 uint64_t frame_length = kFrameHeaderTests[i].frame_length; |
370 | 370 |
371 WebSocketFrameParser parser; | 371 WebSocketFrameParser parser; |
372 | 372 |
373 ScopedVector<WebSocketFrameChunk> frames; | 373 ScopedVector<WebSocketFrameChunk> frames; |
374 // Feed each byte to the parser to see if the parser behaves correctly | 374 // Feed each byte to the parser to see if the parser behaves correctly |
375 // when it receives partial frame header. | 375 // when it receives partial frame header. |
376 size_t last_byte_offset = frame_header_length - 1; | 376 size_t last_byte_offset = frame_header_length - 1; |
377 for (size_t j = 0; j < frame_header_length; ++j) { | 377 for (size_t j = 0; j < frame_header_length; ++j) { |
378 bool failed = | 378 bool failed = |
379 kFrameHeaderTests[i].error_code != kWebSocketNormalClosure && | 379 kFrameHeaderTests[i].error_code != kWebSocketNormalClosure && |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 EXPECT_EQ(reserved3, header->reserved3); | 567 EXPECT_EQ(reserved3, header->reserved3); |
568 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode); | 568 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, header->opcode); |
569 EXPECT_FALSE(header->masked); | 569 EXPECT_FALSE(header->masked); |
570 EXPECT_EQ(0u, header->payload_length); | 570 EXPECT_EQ(0u, header->payload_length); |
571 } | 571 } |
572 } | 572 } |
573 | 573 |
574 } // Unnamed namespace | 574 } // Unnamed namespace |
575 | 575 |
576 } // namespace net | 576 } // namespace net |
OLD | NEW |