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
3 // found in the LICENSE file.
5 #include "net/websockets/websocket_frame_parser.h"
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/port.h"
13 #include "net/base/io_buffer.h"
14 #include "net/websockets/websocket_frame.h"
15 #include "testing/gtest/include/gtest/gtest.h"
21 const char kHello
[] = "Hello, world!";
22 const uint64 kHelloLength
= arraysize(kHello
) - 1;
23 const char kHelloFrame
[] = "\x81\x0DHello, world!";
24 const uint64 kHelloFrameLength
= arraysize(kHelloFrame
) - 1;
25 const char kMaskedHelloFrame
[] =
26 "\x81\x8D\xDE\xAD\xBE\xEF"
27 "\x96\xC8\xD2\x83\xB1\x81\x9E\x98\xB1\xDF\xD2\x8B\xFF";
28 const uint64 kMaskedHelloFrameLength
= arraysize(kMaskedHelloFrame
) - 1;
30 struct FrameHeaderTestCase
{
31 const char* frame_header
;
32 size_t frame_header_length
;
34 WebSocketError error_code
;
37 const FrameHeaderTestCase kFrameHeaderTests
[] = {
38 { "\x81\x00", 2, GG_UINT64_C(0), WEB_SOCKET_OK
},
39 { "\x81\x7D", 2, GG_UINT64_C(125), WEB_SOCKET_OK
},
40 { "\x81\x7E\x00\x7E", 4, GG_UINT64_C(126), WEB_SOCKET_OK
},
41 { "\x81\x7E\xFF\xFF", 4, GG_UINT64_C(0xFFFF), WEB_SOCKET_OK
},
42 { "\x81\x7F\x00\x00\x00\x00\x00\x01\x00\x00", 10, GG_UINT64_C(0x10000),
44 { "\x81\x7F\x00\x00\x00\x00\x7F\xFF\xFF\xFF", 10, GG_UINT64_C(0x7FFFFFFF),
46 { "\x81\x7F\x00\x00\x00\x00\x80\x00\x00\x00", 10, GG_UINT64_C(0x80000000),
47 WEB_SOCKET_ERR_MESSAGE_TOO_BIG
},
48 { "\x81\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 10,
49 GG_UINT64_C(0x7FFFFFFFFFFFFFFF), WEB_SOCKET_ERR_MESSAGE_TOO_BIG
}
51 const int kNumFrameHeaderTests
= arraysize(kFrameHeaderTests
);
53 TEST(WebSocketFrameParserTest
, DecodeNormalFrame
) {
54 WebSocketFrameParser parser
;
56 ScopedVector
<WebSocketFrameChunk
> frames
;
57 EXPECT_TRUE(parser
.Decode(kHelloFrame
, kHelloFrameLength
, &frames
));
58 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
59 ASSERT_EQ(1u, frames
.size());
60 WebSocketFrameChunk
* frame
= frames
[0];
61 ASSERT_TRUE(frame
!= NULL
);
62 const WebSocketFrameHeader
* header
= frame
->header
.get();
63 EXPECT_TRUE(header
!= NULL
);
65 EXPECT_TRUE(header
->final
);
66 EXPECT_FALSE(header
->reserved1
);
67 EXPECT_FALSE(header
->reserved2
);
68 EXPECT_FALSE(header
->reserved3
);
69 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header
->opcode
);
70 EXPECT_FALSE(header
->masked
);
71 EXPECT_EQ(kHelloLength
, header
->payload_length
);
73 EXPECT_TRUE(frame
->final_chunk
);
75 ASSERT_EQ(static_cast<int>(kHelloLength
), frame
->data
->size());
76 EXPECT_TRUE(std::equal(kHello
, kHello
+ kHelloLength
, frame
->data
->data()));
79 TEST(WebSocketFrameParserTest
, DecodeMaskedFrame
) {
80 WebSocketFrameParser parser
;
82 ScopedVector
<WebSocketFrameChunk
> frames
;
83 EXPECT_TRUE(parser
.Decode(kMaskedHelloFrame
, kMaskedHelloFrameLength
,
85 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
86 ASSERT_EQ(1u, frames
.size());
87 WebSocketFrameChunk
* frame
= frames
[0];
88 ASSERT_TRUE(frame
!= NULL
);
89 const WebSocketFrameHeader
* header
= frame
->header
.get();
90 EXPECT_TRUE(header
!= NULL
);
92 EXPECT_TRUE(header
->final
);
93 EXPECT_FALSE(header
->reserved1
);
94 EXPECT_FALSE(header
->reserved2
);
95 EXPECT_FALSE(header
->reserved3
);
96 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header
->opcode
);
97 EXPECT_TRUE(header
->masked
);
98 EXPECT_EQ(kHelloLength
, header
->payload_length
);
100 EXPECT_TRUE(frame
->final_chunk
);
102 ASSERT_EQ(static_cast<int>(kHelloLength
), frame
->data
->size());
103 EXPECT_TRUE(std::equal(kHello
, kHello
+ kHelloLength
, frame
->data
->data()));
106 TEST(WebSocketFrameParserTest
, DecodeManyFrames
) {
110 const char* expected_payload
;
111 size_t expected_payload_length
;
113 static const Input kInputs
[] = {
114 // Each |frame| data is split into two string literals because C++ lexers
115 // consume unlimited number of hex characters in a hex character escape
116 // (e.g. "\x05F" is not treated as { '\x5', 'F', '\0' } but as
117 // { '\x5F', '\0' }).
118 { "\x81\x05" "First", 7, "First", 5 },
119 { "\x81\x06" "Second", 8, "Second", 6 },
120 { "\x81\x05" "Third", 7, "Third", 5 },
121 { "\x81\x06" "Fourth", 8, "Fourth", 6 },
122 { "\x81\x05" "Fifth", 7, "Fifth", 5 },
123 { "\x81\x05" "Sixth", 7, "Sixth", 5 },
124 { "\x81\x07" "Seventh", 9, "Seventh", 7 },
125 { "\x81\x06" "Eighth", 8, "Eighth", 6 },
126 { "\x81\x05" "Ninth", 7, "Ninth", 5 },
127 { "\x81\x05" "Tenth", 7, "Tenth", 5 }
129 static const int kNumInputs
= ARRAYSIZE_UNSAFE(kInputs
);
131 std::vector
<char> input
;
132 // Concatenate all frames.
133 for (int i
= 0; i
< kNumInputs
; ++i
) {
134 input
.insert(input
.end(),
136 kInputs
[i
].frame
+ kInputs
[i
].frame_length
);
139 WebSocketFrameParser parser
;
141 ScopedVector
<WebSocketFrameChunk
> frames
;
142 EXPECT_TRUE(parser
.Decode(&input
.front(), input
.size(), &frames
));
143 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
144 ASSERT_EQ(static_cast<size_t>(kNumInputs
), frames
.size());
146 for (int i
= 0; i
< kNumInputs
; ++i
) {
147 WebSocketFrameChunk
* frame
= frames
[i
];
148 EXPECT_TRUE(frame
!= NULL
);
151 EXPECT_TRUE(frame
->final_chunk
);
152 ASSERT_EQ(kInputs
[i
].expected_payload_length
,
153 static_cast<uint64
>(frame
->data
->size()));
154 EXPECT_TRUE(std::equal(
155 kInputs
[i
].expected_payload
,
156 kInputs
[i
].expected_payload
+ kInputs
[i
].expected_payload_length
,
157 frame
->data
->data()));
159 const WebSocketFrameHeader
* header
= frame
->header
.get();
160 EXPECT_TRUE(header
!= NULL
);
163 EXPECT_TRUE(header
->final
);
164 EXPECT_FALSE(header
->reserved1
);
165 EXPECT_FALSE(header
->reserved2
);
166 EXPECT_FALSE(header
->reserved3
);
167 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header
->opcode
);
168 EXPECT_FALSE(header
->masked
);
169 EXPECT_EQ(kInputs
[i
].expected_payload_length
, header
->payload_length
);
173 TEST(WebSocketFrameParserTest
, DecodePartialFrame
) {
174 static const size_t kFrameHeaderSize
= 2;
176 for (size_t cutting_pos
= 0; cutting_pos
< kHelloLength
; ++cutting_pos
) {
177 std::vector
<char> input1(kHelloFrame
,
178 kHelloFrame
+ kFrameHeaderSize
+ cutting_pos
);
179 std::vector
<char> input2(kHelloFrame
+ input1
.size(),
180 kHelloFrame
+ kHelloFrameLength
);
182 std::vector
<char> expected1(kHello
, kHello
+ cutting_pos
);
183 std::vector
<char> expected2(kHello
+ cutting_pos
, kHello
+ kHelloLength
);
185 WebSocketFrameParser parser
;
187 ScopedVector
<WebSocketFrameChunk
> frames1
;
188 EXPECT_TRUE(parser
.Decode(&input1
.front(), input1
.size(), &frames1
));
189 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
190 EXPECT_EQ(1u, frames1
.size());
191 if (frames1
.size() != 1u)
193 WebSocketFrameChunk
* frame1
= frames1
[0];
194 EXPECT_TRUE(frame1
!= NULL
);
197 EXPECT_FALSE(frame1
->final_chunk
);
198 if (expected1
.size() == 0) {
199 EXPECT_EQ(NULL
, frame1
->data
.get());
201 ASSERT_EQ(cutting_pos
, static_cast<size_t>(frame1
->data
->size()));
202 EXPECT_TRUE(std::equal(expected1
.begin(),
204 frame1
->data
->data()));
206 const WebSocketFrameHeader
* header1
= frame1
->header
.get();
207 EXPECT_TRUE(header1
!= NULL
);
210 EXPECT_TRUE(header1
->final
);
211 EXPECT_FALSE(header1
->reserved1
);
212 EXPECT_FALSE(header1
->reserved2
);
213 EXPECT_FALSE(header1
->reserved3
);
214 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header1
->opcode
);
215 EXPECT_FALSE(header1
->masked
);
216 EXPECT_EQ(kHelloLength
, header1
->payload_length
);
218 ScopedVector
<WebSocketFrameChunk
> frames2
;
219 EXPECT_TRUE(parser
.Decode(&input2
.front(), input2
.size(), &frames2
));
220 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
221 EXPECT_EQ(1u, frames2
.size());
222 if (frames2
.size() != 1u)
224 WebSocketFrameChunk
* frame2
= frames2
[0];
225 EXPECT_TRUE(frame2
!= NULL
);
228 EXPECT_TRUE(frame2
->final_chunk
);
229 if (expected2
.size() == 0) {
230 EXPECT_EQ(NULL
, frame2
->data
.get());
232 ASSERT_EQ(expected2
.size(), static_cast<uint64
>(frame2
->data
->size()));
233 EXPECT_TRUE(std::equal(expected2
.begin(),
235 frame2
->data
->data()));
237 const WebSocketFrameHeader
* header2
= frame2
->header
.get();
238 EXPECT_TRUE(header2
== NULL
);
242 TEST(WebSocketFrameParserTest
, DecodePartialMaskedFrame
) {
243 static const size_t kFrameHeaderSize
= 6;
245 for (size_t cutting_pos
= 0; cutting_pos
< kHelloLength
; ++cutting_pos
) {
246 std::vector
<char> input1(
248 kMaskedHelloFrame
+ kFrameHeaderSize
+ cutting_pos
);
249 std::vector
<char> input2(kMaskedHelloFrame
+ input1
.size(),
250 kMaskedHelloFrame
+ kMaskedHelloFrameLength
);
252 std::vector
<char> expected1(kHello
, kHello
+ cutting_pos
);
253 std::vector
<char> expected2(kHello
+ cutting_pos
, kHello
+ kHelloLength
);
255 WebSocketFrameParser parser
;
257 ScopedVector
<WebSocketFrameChunk
> frames1
;
258 EXPECT_TRUE(parser
.Decode(&input1
.front(), input1
.size(), &frames1
));
259 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
260 EXPECT_EQ(1u, frames1
.size());
261 if (frames1
.size() != 1u)
263 WebSocketFrameChunk
* frame1
= frames1
[0];
264 EXPECT_TRUE(frame1
!= NULL
);
267 EXPECT_FALSE(frame1
->final_chunk
);
268 if (expected1
.size() == 0) {
269 EXPECT_EQ(NULL
, frame1
->data
.get());
271 ASSERT_EQ(expected1
.size(), static_cast<uint64
>(frame1
->data
->size()));
272 EXPECT_TRUE(std::equal(expected1
.begin(),
274 frame1
->data
->data()));
276 const WebSocketFrameHeader
* header1
= frame1
->header
.get();
277 EXPECT_TRUE(header1
!= NULL
);
280 EXPECT_TRUE(header1
->final
);
281 EXPECT_FALSE(header1
->reserved1
);
282 EXPECT_FALSE(header1
->reserved2
);
283 EXPECT_FALSE(header1
->reserved3
);
284 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header1
->opcode
);
285 EXPECT_TRUE(header1
->masked
);
286 EXPECT_EQ(kHelloLength
, header1
->payload_length
);
288 ScopedVector
<WebSocketFrameChunk
> frames2
;
289 EXPECT_TRUE(parser
.Decode(&input2
.front(), input2
.size(), &frames2
));
290 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
291 EXPECT_EQ(1u, frames2
.size());
292 if (frames2
.size() != 1u)
294 WebSocketFrameChunk
* frame2
= frames2
[0];
295 EXPECT_TRUE(frame2
!= NULL
);
298 EXPECT_TRUE(frame2
->final_chunk
);
299 if (expected2
.size() == 0) {
300 EXPECT_EQ(NULL
, frame2
->data
.get());
302 ASSERT_EQ(expected2
.size(), static_cast<uint64
>(frame2
->data
->size()));
303 EXPECT_TRUE(std::equal(expected2
.begin(),
305 frame2
->data
->data()));
307 const WebSocketFrameHeader
* header2
= frame2
->header
.get();
308 EXPECT_TRUE(header2
== NULL
);
312 TEST(WebSocketFrameParserTest
, DecodeFramesOfVariousLengths
) {
313 for (int i
= 0; i
< kNumFrameHeaderTests
; ++i
) {
314 const char* frame_header
= kFrameHeaderTests
[i
].frame_header
;
315 size_t frame_header_length
= kFrameHeaderTests
[i
].frame_header_length
;
316 uint64 frame_length
= kFrameHeaderTests
[i
].frame_length
;
318 std::vector
<char> input(frame_header
, frame_header
+ frame_header_length
);
319 // Limit the payload size not to flood the console on failure.
320 static const uint64 kMaxPayloadSize
= 200;
321 uint64 input_payload_size
= std::min(frame_length
, kMaxPayloadSize
);
322 input
.insert(input
.end(), input_payload_size
, 'a');
324 WebSocketFrameParser parser
;
326 ScopedVector
<WebSocketFrameChunk
> frames
;
327 EXPECT_EQ(kFrameHeaderTests
[i
].error_code
== WEB_SOCKET_OK
,
328 parser
.Decode(&input
.front(), input
.size(), &frames
));
329 EXPECT_EQ(kFrameHeaderTests
[i
].error_code
, parser
.websocket_error());
330 if (kFrameHeaderTests
[i
].error_code
!= WEB_SOCKET_OK
) {
331 EXPECT_EQ(0u, frames
.size());
333 EXPECT_EQ(1u, frames
.size());
335 if (frames
.size() != 1u)
337 WebSocketFrameChunk
* frame
= frames
[0];
338 EXPECT_TRUE(frame
!= NULL
);
341 if (frame_length
== input_payload_size
) {
342 EXPECT_TRUE(frame
->final_chunk
);
344 EXPECT_FALSE(frame
->final_chunk
);
346 std::vector
<char> expected_payload(input_payload_size
, 'a');
347 if (expected_payload
.size() == 0) {
348 EXPECT_EQ(NULL
, frame
->data
.get());
350 ASSERT_EQ(expected_payload
.size(),
351 static_cast<uint64
>(frame
->data
->size()));
352 EXPECT_TRUE(std::equal(
353 expected_payload
.begin(),
354 expected_payload
.end(),
355 frame
->data
->data()));
357 const WebSocketFrameHeader
* header
= frame
->header
.get();
358 EXPECT_TRUE(header
!= NULL
);
361 EXPECT_TRUE(header
->final
);
362 EXPECT_FALSE(header
->reserved1
);
363 EXPECT_FALSE(header
->reserved2
);
364 EXPECT_FALSE(header
->reserved3
);
365 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header
->opcode
);
366 EXPECT_FALSE(header
->masked
);
367 EXPECT_EQ(frame_length
, header
->payload_length
);
371 TEST(WebSocketFrameParserTest
, DecodePartialHeader
) {
372 for (int i
= 0; i
< kNumFrameHeaderTests
; ++i
) {
373 const char* frame_header
= kFrameHeaderTests
[i
].frame_header
;
374 size_t frame_header_length
= kFrameHeaderTests
[i
].frame_header_length
;
375 uint64 frame_length
= kFrameHeaderTests
[i
].frame_length
;
377 WebSocketFrameParser parser
;
379 ScopedVector
<WebSocketFrameChunk
> frames
;
380 // Feed each byte to the parser to see if the parser behaves correctly
381 // when it receives partial frame header.
382 size_t last_byte_offset
= frame_header_length
- 1;
383 for (size_t j
= 0; j
< frame_header_length
; ++j
) {
384 bool failed
= kFrameHeaderTests
[i
].error_code
!= WEB_SOCKET_OK
&&
385 j
== last_byte_offset
;
386 EXPECT_EQ(!failed
, parser
.Decode(frame_header
+ j
, 1, &frames
));
388 EXPECT_EQ(kFrameHeaderTests
[i
].error_code
, parser
.websocket_error());
390 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
392 if (kFrameHeaderTests
[i
].error_code
== WEB_SOCKET_OK
&&
393 j
== last_byte_offset
) {
394 EXPECT_EQ(1u, frames
.size());
396 EXPECT_EQ(0u, frames
.size());
399 if (frames
.size() != 1u)
401 WebSocketFrameChunk
* frame
= frames
[0];
402 EXPECT_TRUE(frame
!= NULL
);
405 if (frame_length
== 0u) {
406 EXPECT_TRUE(frame
->final_chunk
);
408 EXPECT_FALSE(frame
->final_chunk
);
410 EXPECT_EQ(NULL
, frame
->data
.get());
411 const WebSocketFrameHeader
* header
= frame
->header
.get();
412 EXPECT_TRUE(header
!= NULL
);
415 EXPECT_TRUE(header
->final
);
416 EXPECT_FALSE(header
->reserved1
);
417 EXPECT_FALSE(header
->reserved2
);
418 EXPECT_FALSE(header
->reserved3
);
419 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header
->opcode
);
420 EXPECT_FALSE(header
->masked
);
421 EXPECT_EQ(frame_length
, header
->payload_length
);
425 TEST(WebSocketFrameParserTest
, InvalidLengthEncoding
) {
427 const char* frame_header
;
428 size_t frame_header_length
;
430 static const TestCase kTests
[] = {
431 // For frames with two-byte extended length field, the payload length
432 // should be 126 (0x7E) bytes or more.
433 { "\x81\x7E\x00\x00", 4 },
434 { "\x81\x7E\x00\x7D", 4 },
435 // For frames with eight-byte extended length field, the payload length
436 // should be 0x10000 bytes or more.
437 { "\x81\x7F\x00\x00\x00\x00\x00\x00\x00\x00", 10 },
438 { "\x81\x7E\x00\x00\x00\x00\x00\x00\xFF\xFF", 10 },
440 static const int kNumTests
= ARRAYSIZE_UNSAFE(kTests
);
442 for (int i
= 0; i
< kNumTests
; ++i
) {
443 const char* frame_header
= kTests
[i
].frame_header
;
444 size_t frame_header_length
= kTests
[i
].frame_header_length
;
446 WebSocketFrameParser parser
;
448 ScopedVector
<WebSocketFrameChunk
> frames
;
449 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
450 EXPECT_FALSE(parser
.Decode(frame_header
, frame_header_length
, &frames
));
451 EXPECT_EQ(WEB_SOCKET_ERR_PROTOCOL_ERROR
, parser
.websocket_error());
452 EXPECT_EQ(0u, frames
.size());
454 // Once the parser has failed, it no longer accepts any input (even if
455 // the input is empty).
456 EXPECT_FALSE(parser
.Decode("", 0, &frames
));
457 EXPECT_EQ(WEB_SOCKET_ERR_PROTOCOL_ERROR
, parser
.websocket_error());
458 EXPECT_EQ(0u, frames
.size());
462 TEST(WebSocketFrameParserTest
, FrameTypes
) {
464 const char* frame_header
;
465 size_t frame_header_length
;
466 WebSocketFrameHeader::OpCode opcode
;
468 static const TestCase kTests
[] = {
469 { "\x80\x00", 2, WebSocketFrameHeader::kOpCodeContinuation
},
470 { "\x81\x00", 2, WebSocketFrameHeader::kOpCodeText
},
471 { "\x82\x00", 2, WebSocketFrameHeader::kOpCodeBinary
},
472 { "\x88\x00", 2, WebSocketFrameHeader::kOpCodeClose
},
473 { "\x89\x00", 2, WebSocketFrameHeader::kOpCodePing
},
474 { "\x8A\x00", 2, WebSocketFrameHeader::kOpCodePong
},
475 // These are undefined opcodes, but the parser needs to be able to parse
477 { "\x83\x00", 2, 0x3 },
478 { "\x84\x00", 2, 0x4 },
479 { "\x85\x00", 2, 0x5 },
480 { "\x86\x00", 2, 0x6 },
481 { "\x87\x00", 2, 0x7 },
482 { "\x8B\x00", 2, 0xB },
483 { "\x8C\x00", 2, 0xC },
484 { "\x8D\x00", 2, 0xD },
485 { "\x8E\x00", 2, 0xE },
486 { "\x8F\x00", 2, 0xF }
488 static const int kNumTests
= ARRAYSIZE_UNSAFE(kTests
);
490 for (int i
= 0; i
< kNumTests
; ++i
) {
491 const char* frame_header
= kTests
[i
].frame_header
;
492 size_t frame_header_length
= kTests
[i
].frame_header_length
;
493 WebSocketFrameHeader::OpCode opcode
= kTests
[i
].opcode
;
495 WebSocketFrameParser parser
;
497 ScopedVector
<WebSocketFrameChunk
> frames
;
498 EXPECT_TRUE(parser
.Decode(frame_header
, frame_header_length
, &frames
));
499 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
500 EXPECT_EQ(1u, frames
.size());
501 if (frames
.size() != 1u)
503 WebSocketFrameChunk
* frame
= frames
[0];
504 EXPECT_TRUE(frame
!= NULL
);
507 EXPECT_TRUE(frame
->final_chunk
);
508 EXPECT_EQ(NULL
, frame
->data
.get());
509 const WebSocketFrameHeader
* header
= frame
->header
.get();
510 EXPECT_TRUE(header
!= NULL
);
513 EXPECT_TRUE(header
->final
);
514 EXPECT_FALSE(header
->reserved1
);
515 EXPECT_FALSE(header
->reserved2
);
516 EXPECT_FALSE(header
->reserved3
);
517 EXPECT_EQ(opcode
, header
->opcode
);
518 EXPECT_FALSE(header
->masked
);
519 EXPECT_EQ(0u, header
->payload_length
);
523 TEST(WebSocketFrameParserTest
, FinalBitAndReservedBits
) {
525 const char* frame_header
;
526 size_t frame_header_length
;
532 static const TestCase kTests
[] = {
533 { "\x81\x00", 2, true, false, false, false },
534 { "\x01\x00", 2, false, false, false, false },
535 { "\xC1\x00", 2, true, true, false, false },
536 { "\xA1\x00", 2, true, false, true, false },
537 { "\x91\x00", 2, true, false, false, true },
538 { "\x71\x00", 2, false, true, true, true },
539 { "\xF1\x00", 2, true, true, true, true }
541 static const int kNumTests
= ARRAYSIZE_UNSAFE(kTests
);
543 for (int i
= 0; i
< kNumTests
; ++i
) {
544 const char* frame_header
= kTests
[i
].frame_header
;
545 size_t frame_header_length
= kTests
[i
].frame_header_length
;
546 bool final
= kTests
[i
].final
;
547 bool reserved1
= kTests
[i
].reserved1
;
548 bool reserved2
= kTests
[i
].reserved2
;
549 bool reserved3
= kTests
[i
].reserved3
;
551 WebSocketFrameParser parser
;
553 ScopedVector
<WebSocketFrameChunk
> frames
;
554 EXPECT_TRUE(parser
.Decode(frame_header
, frame_header_length
, &frames
));
555 EXPECT_EQ(WEB_SOCKET_OK
, parser
.websocket_error());
556 EXPECT_EQ(1u, frames
.size());
557 if (frames
.size() != 1u)
559 WebSocketFrameChunk
* frame
= frames
[0];
560 EXPECT_TRUE(frame
!= NULL
);
563 EXPECT_TRUE(frame
->final_chunk
);
564 EXPECT_EQ(NULL
, frame
->data
.get());
565 const WebSocketFrameHeader
* header
= frame
->header
.get();
566 EXPECT_TRUE(header
!= NULL
);
569 EXPECT_EQ(final
, header
->final
);
570 EXPECT_EQ(reserved1
, header
->reserved1
);
571 EXPECT_EQ(reserved2
, header
->reserved2
);
572 EXPECT_EQ(reserved3
, header
->reserved3
);
573 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, header
->opcode
);
574 EXPECT_FALSE(header
->masked
);
575 EXPECT_EQ(0u, header
->payload_length
);
579 } // Unnamed namespace