Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: net/spdy/spdy_framer_test.cc

Issue 9618002: SPDY - integration of spdy/3 code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <algorithm> 5 #include <algorithm>
6 #include <iostream> 6 #include <iostream>
7 7
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "net/spdy/spdy_framer.h" 9 #include "net/spdy/spdy_framer.h"
10 #include "net/spdy/spdy_protocol.h" 10 #include "net/spdy/spdy_protocol.h"
11 #include "net/spdy/spdy_frame_builder.h" 11 #include "net/spdy/spdy_frame_builder.h"
12 #include "testing/platform_test.h" 12 #include "testing/platform_test.h"
13 13
14 namespace {
15
16 // The current default spdy version as a byte to be included in const
17 // byte arrays below. Name choice is unfortunate, but better to fit to four
18 // bytes than not.
19 unsigned char kVer = SPDY_VERSION_FOR_TESTS;
Ryan Hamilton 2012/03/09 19:09:58 We need to test both spdy2 and spdy2, right? I th
ramant (doing other things) 2012/03/10 01:14:09 Done.
20
21 spdy::SpdySetting SpdySettingFromWireFormat(uint32 key, uint32 value) {
22 return spdy::SpdySetting(
23 spdy::SettingsFlagsAndId::FromWireFormat(SPDY_VERSION_FOR_TESTS, key),
24 value);
25 }
26
27 } // namespace
28
14 namespace spdy { 29 namespace spdy {
15 30
16 namespace test { 31 namespace test {
17 32
33 static const size_t kMaxDecompressedSize = 1024;
34
35 class SpdyFramerTestUtil {
36 public:
37 // Decompress a single frame using the decompression context held by
38 // the SpdyFramer. The implemention is meant for use only in tests
Ryan Hamilton 2012/03/09 19:09:58 Since it is defined in a _test file, I don't think
ramant (doing other things) 2012/03/10 01:14:09 Done.
39 // and will CHECK fail if the input is anything other than a single,
40 // well-formed compressed frame.
41 //
42 // Returns a new decompressed SpdyFrame.
43 template<class SpdyFrameType> static SpdyFrame* DecompressFrame(
44 SpdyFramer* framer, const SpdyFrameType& frame) {
45 DecompressionVisitor visitor;
46 framer->set_visitor(&visitor);
47 size_t input_size = frame.length() + SpdyFrame::kHeaderSize;
48 CHECK_EQ(input_size, framer->ProcessInput(frame.data(), input_size));
49 CHECK_EQ(SpdyFramer::SPDY_RESET, framer->state());
50 framer->set_visitor(NULL);
51
52 char* buffer = visitor.ReleaseBuffer();
53 CHECK(buffer);
54 SpdyFrame* decompressed_frame = new SpdyFrame(buffer, true);
55 decompressed_frame->set_length(visitor.size() - SpdyFrame::kHeaderSize);
56 return decompressed_frame;
57 }
58
59 class DecompressionVisitor : public SpdyFramerVisitorInterface {
60 public:
61 DecompressionVisitor()
62 : buffer_(NULL), size_(0), finished_(false), allow_data_frames_(false) {
63 }
64
65 virtual void OnControl(const SpdyControlFrame* frame) {
66 CHECK(frame->has_header_block());
67 CHECK(!buffer_.get());
68 CHECK_EQ(size_, 0u);
69 CHECK(!finished_);
70
71 int32 control_frame_header_size = 0;
72 switch (frame->type()) {
73 case SYN_STREAM:
74 control_frame_header_size = SpdySynStreamControlFrame::size();
75 break;
76 case SYN_REPLY:
77 control_frame_header_size = SpdySynReplyControlFrame::size();
78 break;
79 case HEADERS:
80 control_frame_header_size = SpdyHeadersControlFrame::size();
81 break;
82 default:
83 LOG(FATAL);
84 return;
85 }
86
87 // Allocate space for the frame, and the copy header over.
88 buffer_.reset(new char[kMaxDecompressedSize]);
89 memcpy(buffer_.get(), frame->data(), control_frame_header_size);
90 size_ += control_frame_header_size;
91 }
92
93 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
94 const char* header_data,
95 size_t len) {
96 CHECK(buffer_.get() != NULL);
97 CHECK_GE(kMaxDecompressedSize, size_ + len);
98 CHECK(!finished_);
99 if (len != 0) {
100 memcpy(buffer_.get() + size_, header_data, len);
101 size_ += len;
102 } else {
103 // Done.
104 finished_ = true;
105 }
106 return true;
107 }
108
109 virtual bool OnCredentialFrameData(const char* header_data,
110 size_t len) {
111 LOG(FATAL) << "Unexpected CREDENTIAL Frame";
112 return false;
113 }
114
115 virtual void OnError(SpdyFramer* framer) { LOG(FATAL); }
116 virtual void OnDataFrameHeader(const SpdyDataFrame* frame) {
117 // For most tests, this class does not expect to see OnDataFrameHeader
118 // calls. Individual tests can override this if they need to.
119 if (!allow_data_frames_) {
120 LOG(FATAL) << "Unexpected data frame header";
121 }
122 }
123 virtual void OnStreamFrameData(SpdyStreamId stream_id,
124 const char* data,
125 size_t len) {
126 LOG(FATAL);
127 }
128 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
129 LOG(FATAL);
130 }
131
132 char* ReleaseBuffer() {
133 CHECK(finished_);
134 return buffer_.release();
135 }
136
137 size_t size() const {
138 CHECK(finished_);
139 return size_;
140 }
141 void set_allow_data_frames(bool allow) { allow_data_frames_ = allow; }
142
143 private:
144 scoped_array<char> buffer_;
145 size_t size_;
146 bool finished_;
147 bool allow_data_frames_;
148
149 DISALLOW_COPY_AND_ASSIGN(DecompressionVisitor);
150 };
151
152 DISALLOW_COPY_AND_ASSIGN(SpdyFramerTestUtil);
153 };
154
18 std::string HexDumpWithMarks(const unsigned char* data, int length, 155 std::string HexDumpWithMarks(const unsigned char* data, int length,
19 const bool* marks, int mark_length) { 156 const bool* marks, int mark_length) {
20 static const char kHexChars[] = "0123456789ABCDEF"; 157 static const char kHexChars[] = "0123456789abcdef";
Ryan Hamilton 2012/03/09 19:09:58 Out of curiosity, why is this changing?
ramant (doing other things) 2012/03/10 01:14:09 Took the change as is from the server. Was trying
21 static const int kColumns = 4; 158 static const int kColumns = 4;
22 159
23 const int kSizeLimit = 1024; 160 const int kSizeLimit = 1024;
24 if (length > kSizeLimit || mark_length > kSizeLimit) { 161 if (length > kSizeLimit || mark_length > kSizeLimit) {
25 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; 162 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
26 length = std::min(length, kSizeLimit); 163 length = std::min(length, kSizeLimit);
27 mark_length = std::min(mark_length, kSizeLimit); 164 mark_length = std::min(mark_length, kSizeLimit);
28 } 165 }
29 166
30 std::string hex; 167 std::string hex;
(...skipping 20 matching lines...) Expand all
51 } 188 }
52 return hex; 189 return hex;
53 } 190 }
54 191
55 void CompareCharArraysWithHexError( 192 void CompareCharArraysWithHexError(
56 const std::string& description, 193 const std::string& description,
57 const unsigned char* actual, 194 const unsigned char* actual,
58 const int actual_len, 195 const int actual_len,
59 const unsigned char* expected, 196 const unsigned char* expected,
60 const int expected_len) { 197 const int expected_len) {
61 const int min_len = actual_len > expected_len ? expected_len : actual_len; 198 const int min_len = (actual_len > expected_len) ? expected_len : actual_len;
Ryan Hamilton 2012/03/09 19:09:58 const int min_len = min(actual_len, expected_len);
ramant (doing other things) 2012/03/10 01:14:09 Done.
62 const int max_len = actual_len > expected_len ? actual_len : expected_len; 199 const int max_len = (actual_len > expected_len) ? actual_len : expected_len;
63 scoped_array<bool> marks(new bool[max_len]); 200 scoped_array<bool> marks(new bool[max_len]);
64 bool identical = (actual_len == expected_len); 201 bool identical = (actual_len == expected_len);
65 for (int i = 0; i < min_len; ++i) { 202 for (int i = 0; i < min_len; ++i) {
66 if (actual[i] != expected[i]) { 203 if (actual[i] != expected[i]) {
67 marks[i] = true; 204 marks[i] = true;
68 identical = false; 205 identical = false;
69 } else { 206 } else {
70 marks[i] = false; 207 marks[i] = false;
71 } 208 }
72 } 209 }
73 for (int i = min_len; i < max_len; ++i) { 210 for (int i = min_len; i < max_len; ++i) {
74 marks[i] = true; 211 marks[i] = true;
75 } 212 }
76 if (identical) return; 213 if (identical) return;
77 ADD_FAILURE() 214 ADD_FAILURE()
78 << "Description:\n" 215 << "Description:\n"
79 << description 216 << description
80 << "\n\nExpected:\n" 217 << "\n\nExpected:\n"
81 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) 218 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
82 << "\nActual:\n" 219 << "\nActual:\n"
83 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); 220 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
84 } 221 }
85 222
86 class TestSpdyVisitor : public SpdyFramerVisitorInterface { 223 class TestSpdyVisitor : public SpdyFramerVisitorInterface {
87 public: 224 public:
88 static const size_t kDefaultHeaderBufferSize = 64 * 1024; 225 static const size_t kDefaultHeaderBufferSize = 64 * 1024;
89 static const size_t kDefaultCredentialBufferSize = 16 * 1024; 226 static const size_t kDefaultCredentialBufferSize = 16 * 1024;
90 227
91 TestSpdyVisitor() 228 TestSpdyVisitor()
92 : use_compression_(false), 229 : framer_(kVer),
230 use_compression_(false),
93 error_count_(0), 231 error_count_(0),
94 syn_frame_count_(0), 232 syn_frame_count_(0),
95 syn_reply_frame_count_(0), 233 syn_reply_frame_count_(0),
96 headers_frame_count_(0), 234 headers_frame_count_(0),
97 goaway_count_(0), 235 goaway_count_(0),
98 credential_count_(0), 236 credential_count_(0),
237 settings_frame_count_(0),
238 setting_count_(0),
99 data_bytes_(0), 239 data_bytes_(0),
100 fin_frame_count_(0), 240 fin_frame_count_(0),
101 fin_flag_count_(0), 241 fin_flag_count_(0),
102 zero_length_data_frame_count_(0), 242 zero_length_data_frame_count_(0),
103 header_blocks_count_(0), 243 header_blocks_count_(0),
104 control_frame_header_data_count_(0), 244 control_frame_header_data_count_(0),
105 zero_length_control_frame_header_data_count_(0), 245 zero_length_control_frame_header_data_count_(0),
106 data_frame_count_(0), 246 data_frame_count_(0),
107 header_buffer_(new char[kDefaultHeaderBufferSize]), 247 header_buffer_(new char[kDefaultHeaderBufferSize]),
108 header_buffer_length_(0), 248 header_buffer_length_(0),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 case HEADERS: 299 case HEADERS:
160 headers_frame_count_++; 300 headers_frame_count_++;
161 InitHeaderStreaming(frame); 301 InitHeaderStreaming(frame);
162 break; 302 break;
163 case GOAWAY: 303 case GOAWAY:
164 goaway_count_++; 304 goaway_count_++;
165 break; 305 break;
166 case CREDENTIAL: 306 case CREDENTIAL:
167 credential_count_++; 307 credential_count_++;
168 break; 308 break;
309 case SETTINGS:
310 settings_frame_count_++;
311 break;
169 default: 312 default:
170 DLOG(FATAL); // Error! 313 DLOG(FATAL); // Error!
171 } 314 }
172 if (frame->flags() & CONTROL_FLAG_FIN) 315 if (frame->flags() & CONTROL_FLAG_FIN)
173 ++fin_flag_count_; 316 ++fin_flag_count_;
174 } 317 }
175 318
319 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) {
320 setting_count_++;
321 }
322
176 bool OnControlFrameHeaderData(SpdyStreamId stream_id, 323 bool OnControlFrameHeaderData(SpdyStreamId stream_id,
177 const char* header_data, 324 const char* header_data,
178 size_t len) { 325 size_t len) {
179 ++control_frame_header_data_count_; 326 ++control_frame_header_data_count_;
180 CHECK_EQ(header_stream_id_, stream_id); 327 CHECK_EQ(header_stream_id_, stream_id);
181 if (len == 0) { 328 if (len == 0) {
182 ++zero_length_control_frame_header_data_count_; 329 ++zero_length_control_frame_header_data_count_;
183 // Indicates end-of-header-block. 330 // Indicates end-of-header-block.
184 CHECK(header_buffer_valid_); 331 CHECK(header_buffer_valid_);
185 bool parsed_headers = SpdyFramer::ParseHeaderBlockInBuffer( 332 bool parsed_headers = framer_.ParseHeaderBlockInBuffer(
186 header_buffer_.get(), header_buffer_length_, &headers_); 333 header_buffer_.get(), header_buffer_length_, &headers_);
187 DCHECK(parsed_headers); 334 DCHECK(parsed_headers);
188 return true; 335 return true;
189 } 336 }
190 const size_t available = header_buffer_size_ - header_buffer_length_; 337 const size_t available = header_buffer_size_ - header_buffer_length_;
191 if (len > available) { 338 if (len > available) {
192 header_buffer_valid_ = false; 339 header_buffer_valid_ = false;
193 return false; 340 return false;
194 } 341 }
195 memcpy(header_buffer_.get() + header_buffer_length_, header_data, len); 342 memcpy(header_buffer_.get() + header_buffer_length_, header_data, len);
196 header_buffer_length_ += len; 343 header_buffer_length_ += len;
197 return true; 344 return true;
198 } 345 }
199 346
200 bool OnCredentialFrameData(const char* credential_data, size_t len) { 347 bool OnCredentialFrameData(const char* credential_data,
348 size_t len) {
201 if (len == 0) { 349 if (len == 0) {
202 if (!framer_.ParseCredentialData(credential_buffer_.get(), 350 if (!framer_.ParseCredentialData(credential_buffer_.get(),
203 credential_buffer_length_, 351 credential_buffer_length_,
204 &credential_)) { 352 &credential_)) {
205 ++error_count_; 353 ++error_count_;
206 } 354 }
207 return true; 355 return true;
208 } 356 }
209 const size_t available = 357 const size_t available =
210 credential_buffer_size_ - credential_buffer_length_; 358 credential_buffer_size_ - credential_buffer_length_;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 SpdyFramer framer_; 413 SpdyFramer framer_;
266 bool use_compression_; 414 bool use_compression_;
267 415
268 // Counters from the visitor callbacks. 416 // Counters from the visitor callbacks.
269 int error_count_; 417 int error_count_;
270 int syn_frame_count_; 418 int syn_frame_count_;
271 int syn_reply_frame_count_; 419 int syn_reply_frame_count_;
272 int headers_frame_count_; 420 int headers_frame_count_;
273 int goaway_count_; 421 int goaway_count_;
274 int credential_count_; 422 int credential_count_;
423 int settings_frame_count_;
424 int setting_count_;
275 int data_bytes_; 425 int data_bytes_;
276 int fin_frame_count_; // The count of RST_STREAM type frames received. 426 int fin_frame_count_; // The count of RST_STREAM type frames received.
277 int fin_flag_count_; // The count of frames with the FIN flag set. 427 int fin_flag_count_; // The count of frames with the FIN flag set.
278 int zero_length_data_frame_count_; // The count of zero-length data frames. 428 int zero_length_data_frame_count_; // The count of zero-length data frames.
279 int header_blocks_count_; 429 int header_blocks_count_;
280 int control_frame_header_data_count_; // The count of chunks received. 430 int control_frame_header_data_count_; // The count of chunks received.
281 // The count of zero-length control frame header data chunks received. 431 // The count of zero-length control frame header data chunks received.
282 int zero_length_control_frame_header_data_count_; 432 int zero_length_control_frame_header_data_count_;
283 int data_frame_count_; 433 int data_frame_count_;
284 434
(...skipping 24 matching lines...) Expand all
309 using spdy::SpdyFramer; 459 using spdy::SpdyFramer;
310 using spdy::SpdyHeaderBlock; 460 using spdy::SpdyHeaderBlock;
311 using spdy::SpdySynStreamControlFrame; 461 using spdy::SpdySynStreamControlFrame;
312 using spdy::kControlFlagMask; 462 using spdy::kControlFlagMask;
313 using spdy::kLengthMask; 463 using spdy::kLengthMask;
314 using spdy::CONTROL_FLAG_NONE; 464 using spdy::CONTROL_FLAG_NONE;
315 using spdy::DATA_FLAG_COMPRESSED; 465 using spdy::DATA_FLAG_COMPRESSED;
316 using spdy::DATA_FLAG_FIN; 466 using spdy::DATA_FLAG_FIN;
317 using spdy::SYN_STREAM; 467 using spdy::SYN_STREAM;
318 using spdy::test::CompareCharArraysWithHexError; 468 using spdy::test::CompareCharArraysWithHexError;
469 using spdy::test::SpdyFramerTestUtil;
319 using spdy::test::TestSpdyVisitor; 470 using spdy::test::TestSpdyVisitor;
320 471
321 namespace spdy { 472 namespace spdy {
322 473
323 TEST(SpdyFrameBuilderTest, WriteLimits) { 474 TEST(SpdyFrameBuilderTest, WriteLimits) {
324 SpdyFrameBuilder builder(kLengthMask + 4); 475 SpdyFrameBuilder builder(kLengthMask + 4);
325 // length field should fail. 476 // length field should fail.
326 EXPECT_FALSE(builder.WriteBytes(reinterpret_cast<const void*>(0x1), 477 EXPECT_FALSE(builder.WriteBytes(reinterpret_cast<const void*>(0x1),
327 kLengthMask + 1)); 478 kLengthMask + 1));
328 EXPECT_EQ(0, builder.length()); 479 EXPECT_EQ(0, builder.length());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 return true; 530 return true;
380 } 531 }
381 }; 532 };
382 533
383 534
384 // Test that we can encode and decode a SpdyHeaderBlock in serialized form. 535 // Test that we can encode and decode a SpdyHeaderBlock in serialized form.
385 TEST_F(SpdyFramerTest, HeaderBlockInBuffer) { 536 TEST_F(SpdyFramerTest, HeaderBlockInBuffer) {
386 SpdyHeaderBlock headers; 537 SpdyHeaderBlock headers;
387 headers["alpha"] = "beta"; 538 headers["alpha"] = "beta";
388 headers["gamma"] = "charlie"; 539 headers["gamma"] = "charlie";
389 SpdyFramer framer; 540 SpdyFramer framer(kVer);
390 541
391 // Encode the header block into a SynStream frame. 542 // Encode the header block into a SynStream frame.
392 scoped_ptr<SpdySynStreamControlFrame> frame( 543 scoped_ptr<SpdySynStreamControlFrame> frame(
393 framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, false, &headers)); 544 framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, false, &headers));
394 EXPECT_TRUE(frame.get() != NULL); 545 EXPECT_TRUE(frame.get() != NULL);
395 std::string serialized_headers(frame->header_block(), 546 std::string serialized_headers(frame->header_block(),
396 frame->header_block_len()); 547 frame->header_block_len());
397 SpdyHeaderBlock new_headers; 548 SpdyHeaderBlock new_headers;
398 EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(), 549 EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
399 serialized_headers.size(), 550 serialized_headers.size(),
400 &new_headers)); 551 &new_headers));
401 552
402 EXPECT_EQ(headers.size(), new_headers.size()); 553 EXPECT_EQ(headers.size(), new_headers.size());
403 EXPECT_EQ(headers["alpha"], new_headers["alpha"]); 554 EXPECT_EQ(headers["alpha"], new_headers["alpha"]);
404 EXPECT_EQ(headers["gamma"], new_headers["gamma"]); 555 EXPECT_EQ(headers["gamma"], new_headers["gamma"]);
405 } 556 }
406 557
407 // Test that if there's not a full frame, we fail to parse it. 558 // Test that if there's not a full frame, we fail to parse it.
408 TEST_F(SpdyFramerTest, UndersizedHeaderBlockInBuffer) { 559 TEST_F(SpdyFramerTest, UndersizedHeaderBlockInBuffer) {
409 SpdyHeaderBlock headers; 560 SpdyHeaderBlock headers;
410 headers["alpha"] = "beta"; 561 headers["alpha"] = "beta";
411 headers["gamma"] = "charlie"; 562 headers["gamma"] = "charlie";
412 SpdyFramer framer; 563 SpdyFramer framer(kVer);
413 564
414 // Encode the header block into a SynStream frame. 565 // Encode the header block into a SynStream frame.
415 scoped_ptr<SpdySynStreamControlFrame> frame( 566 scoped_ptr<SpdySynStreamControlFrame> frame(
416 framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, false, &headers)); 567 framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, false, &headers));
417 EXPECT_TRUE(frame.get() != NULL); 568 EXPECT_TRUE(frame.get() != NULL);
418 569
419 std::string serialized_headers(frame->header_block(), 570 std::string serialized_headers(frame->header_block(),
420 frame->header_block_len()); 571 frame->header_block_len());
421 SpdyHeaderBlock new_headers; 572 SpdyHeaderBlock new_headers;
422 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(), 573 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
423 serialized_headers.size() - 2, 574 serialized_headers.size() - 2,
424 &new_headers)); 575 &new_headers));
425 } 576 }
426 577
427 TEST_F(SpdyFramerTest, OutOfOrderHeaders) { 578 TEST_F(SpdyFramerTest, OutOfOrderHeaders) {
428 // Frame builder with plentiful buffer size. 579 // Frame builder with plentiful buffer size.
429 SpdyFrameBuilder frame(1024); 580 SpdyFrameBuilder frame(1024);
430 581
431 frame.WriteUInt16(kControlFlagMask | 1); 582 frame.WriteUInt16(kControlFlagMask | 1);
432 frame.WriteUInt16(SYN_STREAM); 583 frame.WriteUInt16(SYN_STREAM);
433 frame.WriteUInt32(0); // Placeholder for the length. 584 frame.WriteUInt32(0); // Placeholder for the length.
434 frame.WriteUInt32(3); // stream_id 585 frame.WriteUInt32(3); // stream_id
435 frame.WriteUInt32(0); // Associated stream id 586 frame.WriteUInt32(0); // Associated stream id
436 frame.WriteUInt16(0); // Priority. 587 frame.WriteUInt16(0); // Priority.
437 588
438 frame.WriteUInt16(2); // Number of headers. 589 if (SPDY_VERSION_FOR_TESTS < 3) {
439 SpdyHeaderBlock::iterator it; 590 frame.WriteUInt16(2); // Number of headers.
440 frame.WriteString("gamma"); 591 frame.WriteString("gamma");
441 frame.WriteString("gamma"); 592 frame.WriteString("gamma");
442 frame.WriteString("alpha"); 593 frame.WriteString("alpha");
443 frame.WriteString("alpha"); 594 frame.WriteString("alpha");
595 } else {
596 frame.WriteUInt32(2); // Number of headers.
597 frame.WriteStringPiece32("gamma");
598 frame.WriteStringPiece32("gamma");
599 frame.WriteStringPiece32("alpha");
600 frame.WriteStringPiece32("alpha");
601 }
444 // write the length 602 // write the length
445 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize); 603 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
446 604
447 SpdyHeaderBlock new_headers; 605 SpdyHeaderBlock new_headers;
448 scoped_ptr<SpdyFrame> control_frame(frame.take()); 606 scoped_ptr<SpdyFrame> control_frame(frame.take());
449 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); 607 SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
450 std::string serialized_headers(syn_frame.header_block(), 608 std::string serialized_headers(syn_frame.header_block(),
451 syn_frame.header_block_len()); 609 syn_frame.header_block_len());
452 SpdyFramer framer; 610 SpdyFramer framer(kVer);
453 framer.set_enable_compression(false); 611 framer.set_enable_compression(false);
454 EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(), 612 EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
455 serialized_headers.size(), 613 serialized_headers.size(),
456 &new_headers)); 614 &new_headers));
457 } 615 }
458 616
617 TEST_F(SpdyFramerTest, CreateCredential) {
618 SpdyFramer framer(kVer);
619
620 {
621 const char kDescription[] = "CREDENTIAL frame";
622 const unsigned char kFrameData[] = {
623 0x80, kVer, 0x00, 0x0A,
624 0x00, 0x00, 0x00, 0x33,
625 0x00, 0x03, 0x00, 0x00,
626 0x00, 0x05, 'p', 'r',
627 'o', 'o', 'f', 0x00,
628 0x00, 0x00, 0x06, 'a',
629 ' ', 'c', 'e', 'r',
630 't', 0x00, 0x00, 0x00,
631 0x0C, 'a', 'n', 'o',
632 't', 'h', 'e', 'r',
633 ' ', 'c', 'e', 'r',
634 't', 0x00, 0x00, 0x00,
635 0x0A, 'f', 'i', 'n',
636 'a', 'l', ' ', 'c',
637 'e', 'r', 't',
638 };
639 SpdyCredential credential;
640 credential.slot = 3;
641 credential.proof = "proof";
642 credential.certs.push_back("a cert");
643 credential.certs.push_back("another cert");
644 credential.certs.push_back("final cert");
645 scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
646 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
647 }
648 }
649
650 TEST_F(SpdyFramerTest, ParseCredentialFrameData) {
651 SpdyFramer framer(kVer);
652
653 {
654 unsigned char kFrameData[] = {
655 0x80, kVer, 0x00, 0x0A,
656 0x00, 0x00, 0x00, 0x33,
657 0x00, 0x03, 0x00, 0x00,
658 0x00, 0x05, 'p', 'r',
659 'o', 'o', 'f', 0x00,
660 0x00, 0x00, 0x06, 'a',
661 ' ', 'c', 'e', 'r',
662 't', 0x00, 0x00, 0x00,
663 0x0C, 'a', 'n', 'o',
664 't', 'h', 'e', 'r',
665 ' ', 'c', 'e', 'r',
666 't', 0x00, 0x00, 0x00,
667 0x0A, 'f', 'i', 'n',
668 'a', 'l', ' ', 'c',
669 'e', 'r', 't',
670 };
671 SpdyCredentialControlFrame frame(reinterpret_cast<char*>(kFrameData),
672 false);
673 SpdyCredential credential;
674 EXPECT_TRUE(SpdyFramer::ParseCredentialData(frame.payload(), frame.length(),
675 &credential));
676 EXPECT_EQ(3u, credential.slot);
677 EXPECT_EQ("proof", credential.proof);
678 EXPECT_EQ("a cert", credential.certs.front());
679 credential.certs.erase(credential.certs.begin());
680 EXPECT_EQ("another cert", credential.certs.front());
681 credential.certs.erase(credential.certs.begin());
682 EXPECT_EQ("final cert", credential.certs.front());
683 credential.certs.erase(credential.certs.begin());
684 EXPECT_TRUE(credential.certs.empty());
685 }
686 }
687
459 TEST_F(SpdyFramerTest, DuplicateHeader) { 688 TEST_F(SpdyFramerTest, DuplicateHeader) {
460 // Frame builder with plentiful buffer size. 689 // Frame builder with plentiful buffer size.
461 SpdyFrameBuilder frame(1024); 690 SpdyFrameBuilder frame(1024);
462 691
463 frame.WriteUInt16(kControlFlagMask | 1); 692 frame.WriteUInt16(kControlFlagMask | 1);
464 frame.WriteUInt16(SYN_STREAM); 693 frame.WriteUInt16(SYN_STREAM);
465 frame.WriteUInt32(0); // Placeholder for the length. 694 frame.WriteUInt32(0); // Placeholder for the length.
466 frame.WriteUInt32(3); // stream_id 695 frame.WriteUInt32(3); // stream_id
467 frame.WriteUInt32(0); // associated stream id 696 frame.WriteUInt32(0); // associated stream id
468 frame.WriteUInt16(0); // Priority. 697 frame.WriteUInt16(0); // Priority.
469 698
470 frame.WriteUInt16(2); // Number of headers. 699 if (SPDY_VERSION_FOR_TESTS < 3) {
471 SpdyHeaderBlock::iterator it; 700 frame.WriteUInt16(2); // Number of headers.
472 frame.WriteString("name"); 701 frame.WriteString("name");
473 frame.WriteString("value1"); 702 frame.WriteString("value1");
474 frame.WriteString("name"); 703 frame.WriteString("name");
475 frame.WriteString("value2"); 704 frame.WriteString("value2");
705 } else {
706 frame.WriteUInt32(2); // Number of headers.
707 frame.WriteStringPiece32("name");
708 frame.WriteStringPiece32("value1");
709 frame.WriteStringPiece32("name");
710 frame.WriteStringPiece32("value2");
711 }
476 // write the length 712 // write the length
477 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize); 713 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
478 714
479 SpdyHeaderBlock new_headers; 715 SpdyHeaderBlock new_headers;
480 scoped_ptr<SpdyFrame> control_frame(frame.take()); 716 scoped_ptr<SpdyFrame> control_frame(frame.take());
481 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); 717 SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
482 std::string serialized_headers(syn_frame.header_block(), 718 std::string serialized_headers(syn_frame.header_block(),
483 syn_frame.header_block_len()); 719 syn_frame.header_block_len());
484 SpdyFramer framer; 720 SpdyFramer framer(kVer);
485 framer.set_enable_compression(false); 721 framer.set_enable_compression(false);
486 // This should fail because duplicate headers are verboten by the spec. 722 // This should fail because duplicate headers are verboten by the spec.
487 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(), 723 EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
488 serialized_headers.size(), 724 serialized_headers.size(),
489 &new_headers)); 725 &new_headers));
490 } 726 }
491 727
492 TEST_F(SpdyFramerTest, MultiValueHeader) { 728 TEST_F(SpdyFramerTest, MultiValueHeader) {
493 // Frame builder with plentiful buffer size. 729 // Frame builder with plentiful buffer size.
494 SpdyFrameBuilder frame(1024); 730 SpdyFrameBuilder frame(1024);
495 731
496 frame.WriteUInt16(kControlFlagMask | 1); 732 frame.WriteUInt16(kControlFlagMask | 1);
497 frame.WriteUInt16(SYN_STREAM); 733 frame.WriteUInt16(SYN_STREAM);
498 frame.WriteUInt32(0); // Placeholder for the length. 734 frame.WriteUInt32(0); // Placeholder for the length.
499 frame.WriteUInt32(3); // stream_id 735 frame.WriteUInt32(3); // stream_id
500 frame.WriteUInt32(0); // associated stream id 736 frame.WriteUInt32(0); // associated stream id
501 frame.WriteUInt16(0); // Priority. 737 frame.WriteUInt16(0); // Priority.
502 738
503 frame.WriteUInt16(1); // Number of headers.
504 SpdyHeaderBlock::iterator it;
505 frame.WriteString("name");
506 std::string value("value1\0value2"); 739 std::string value("value1\0value2");
507 frame.WriteString(value); 740 if (SPDY_VERSION_FOR_TESTS < 3) {
741 frame.WriteUInt16(1); // Number of headers.
742 frame.WriteString("name");
743 frame.WriteString(value);
744 } else {
745 frame.WriteUInt32(1); // Number of headers.
746 frame.WriteStringPiece32("name");
747 frame.WriteStringPiece32(value);
748 }
508 // write the length 749 // write the length
509 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize); 750 frame.WriteUInt32ToOffset(4, frame.length() - SpdyFrame::kHeaderSize);
510 751
511 SpdyHeaderBlock new_headers; 752 SpdyHeaderBlock new_headers;
512 scoped_ptr<SpdyFrame> control_frame(frame.take()); 753 scoped_ptr<SpdyFrame> control_frame(frame.take());
513 SpdySynStreamControlFrame syn_frame(control_frame->data(), false); 754 SpdySynStreamControlFrame syn_frame(control_frame->data(), false);
514 std::string serialized_headers(syn_frame.header_block(), 755 std::string serialized_headers(syn_frame.header_block(),
515 syn_frame.header_block_len()); 756 syn_frame.header_block_len());
516 SpdyFramer framer; 757 SpdyFramer framer(kVer);
517 framer.set_enable_compression(false); 758 framer.set_enable_compression(false);
518 EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(), 759 EXPECT_TRUE(framer.ParseHeaderBlockInBuffer(serialized_headers.c_str(),
519 serialized_headers.size(), 760 serialized_headers.size(),
520 &new_headers)); 761 &new_headers));
521 EXPECT_TRUE(new_headers.find("name") != new_headers.end()); 762 EXPECT_TRUE(new_headers.find("name") != new_headers.end());
522 EXPECT_EQ(value, new_headers.find("name")->second); 763 EXPECT_EQ(value, new_headers.find("name")->second);
523 } 764 }
524 765
525 TEST_F(SpdyFramerTest, BasicCompression) { 766 TEST_F(SpdyFramerTest, BasicCompression) {
526 SpdyHeaderBlock headers; 767 SpdyHeaderBlock headers;
527 headers["server"] = "SpdyServer 1.0"; 768 headers["server"] = "SpdyServer 1.0";
528 headers["date"] = "Mon 12 Jan 2009 12:12:12 PST"; 769 headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
529 headers["status"] = "200"; 770 headers["status"] = "200";
530 headers["version"] = "HTTP/1.1"; 771 headers["version"] = "HTTP/1.1";
531 headers["content-type"] = "text/html"; 772 headers["content-type"] = "text/html";
532 headers["content-length"] = "12"; 773 headers["content-length"] = "12";
533 774
534 SpdyFramer framer; 775 SpdyFramer framer(kVer);
535 framer.set_enable_compression(true); 776 framer.set_enable_compression(true);
536 scoped_ptr<SpdySynStreamControlFrame> 777 scoped_ptr<SpdySynStreamControlFrame>
537 frame1(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, true, 778 frame1(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, true,
538 &headers)); 779 &headers));
539 scoped_ptr<SpdySynStreamControlFrame> 780 scoped_ptr<SpdySynStreamControlFrame>
540 frame2(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, true, 781 frame2(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, true,
541 &headers)); 782 &headers));
542 783
543 // Expect the second frame to be more compact than the first. 784 // Expect the second frame to be more compact than the first.
544 EXPECT_LE(frame2->length(), frame1->length()); 785 EXPECT_LE(frame2->length(), frame1->length());
545 786
546 // Decompress the first frame 787 // Decompress the first frame
547 scoped_ptr<SpdyFrame> frame3(framer.DecompressFrame(*frame1.get())); 788 scoped_ptr<SpdyFrame> frame3(SpdyFramerTestUtil::DecompressFrame(
789 &framer, *frame1.get()));
548 790
549 // Decompress the second frame 791 // Decompress the second frame
550 scoped_ptr<SpdyFrame> frame4(framer.DecompressFrame(*frame2.get())); 792 scoped_ptr<SpdyFrame> frame4(SpdyFramerTestUtil::DecompressFrame(
793 &framer, *frame2.get()));
551 794
552 // Expect frames 3 & 4 to be the same. 795 // Expect frames 3 & 4 to be the same.
553 EXPECT_EQ(0, 796 EXPECT_EQ(0,
554 memcmp(frame3->data(), frame4->data(), 797 memcmp(frame3->data(), frame4->data(),
555 SpdyFrame::kHeaderSize + frame3->length())); 798 SpdyFrame::kHeaderSize + frame3->length()));
556 799
557 800
558 // Expect frames 3 to be the same as a uncompressed frame created 801 // Expect frames 3 to be the same as a uncompressed frame created
559 // from scratch. 802 // from scratch.
560 scoped_ptr<SpdySynStreamControlFrame> 803 scoped_ptr<SpdySynStreamControlFrame>
561 uncompressed_frame(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, 804 uncompressed_frame(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE,
562 false, &headers)); 805 false, &headers));
563 EXPECT_EQ(frame3->length(), uncompressed_frame->length()); 806 EXPECT_EQ(frame3->length(), uncompressed_frame->length());
564 EXPECT_EQ(0, 807 EXPECT_EQ(0,
565 memcmp(frame3->data(), uncompressed_frame->data(), 808 memcmp(frame3->data(), uncompressed_frame->data(),
566 SpdyFrame::kHeaderSize + uncompressed_frame->length())); 809 SpdyFrame::kHeaderSize + uncompressed_frame->length()));
567 } 810 }
568 811
569 TEST_F(SpdyFramerTest, DecompressUncompressedFrame) {
570 SpdyHeaderBlock headers;
571 headers["server"] = "SpdyServer 1.0";
572 headers["date"] = "Mon 12 Jan 2009 12:12:12 PST";
573 headers["status"] = "200";
574 headers["version"] = "HTTP/1.1";
575 headers["content-type"] = "text/html";
576 headers["content-length"] = "12";
577
578 SpdyFramer framer;
579 framer.set_enable_compression(true);
580 scoped_ptr<SpdySynStreamControlFrame>
581 frame1(framer.CreateSynStream(1, 0, 1, CONTROL_FLAG_NONE, false,
582 &headers));
583
584 // Decompress the frame
585 scoped_ptr<SpdyFrame> frame2(framer.DecompressFrame(*frame1.get()));
586
587 EXPECT_EQ(NULL, frame2.get());
588 }
589
590 TEST_F(SpdyFramerTest, Basic) { 812 TEST_F(SpdyFramerTest, Basic) {
591 const unsigned char input[] = { 813 const unsigned char kV2Input[] = {
592 0x80, 0x02, 0x00, 0x01, // SYN Stream #1 814 0x80, kVer, 0x00, 0x01, // SYN Stream #1
593 0x00, 0x00, 0x00, 0x14, 815 0x00, 0x00, 0x00, 0x14,
594 0x00, 0x00, 0x00, 0x01, 816 0x00, 0x00, 0x00, 0x01,
595 0x00, 0x00, 0x00, 0x00, 817 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x01, 818 0x00, 0x00, 0x00, 0x01,
597 0x00, 0x02, 'h', 'h', 819 0x00, 0x02, 'h', 'h',
598 0x00, 0x02, 'v', 'v', 820 0x00, 0x02, 'v', 'v',
599 821
600 0x80, 0x02, 0x00, 0x08, // HEADERS on Stream #1 822 0x80, kVer, 0x00, 0x08, // HEADERS on Stream #1
601 0x00, 0x00, 0x00, 0x18, 823 0x00, 0x00, 0x00, 0x18,
602 0x00, 0x00, 0x00, 0x01, 824 0x00, 0x00, 0x00, 0x01,
603 0x00, 0x00, 0x00, 0x02, 825 0x00, 0x00, 0x00, 0x02,
604 0x00, 0x02, 'h', '2', 826 0x00, 0x02, 'h', '2',
605 0x00, 0x02, 'v', '2', 827 0x00, 0x02, 'v', '2',
606 0x00, 0x02, 'h', '3', 828 0x00, 0x02, 'h', '3',
607 0x00, 0x02, 'v', '3', 829 0x00, 0x02, 'v', '3',
608 830
609 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1 831 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
610 0x00, 0x00, 0x00, 0x0c, 832 0x00, 0x00, 0x00, 0x0c,
611 0xde, 0xad, 0xbe, 0xef, 833 0xde, 0xad, 0xbe, 0xef,
612 0xde, 0xad, 0xbe, 0xef, 834 0xde, 0xad, 0xbe, 0xef,
613 0xde, 0xad, 0xbe, 0xef, 835 0xde, 0xad, 0xbe, 0xef,
614 836
615 0x80, 0x02, 0x00, 0x01, // SYN Stream #3 837 0x80, kVer, 0x00, 0x01, // SYN Stream #3
616 0x00, 0x00, 0x00, 0x0c, 838 0x00, 0x00, 0x00, 0x0c,
617 0x00, 0x00, 0x00, 0x03, 839 0x00, 0x00, 0x00, 0x03,
618 0x00, 0x00, 0x00, 0x00, 840 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 841 0x00, 0x00, 0x00, 0x00,
620 842
621 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3 843 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
622 0x00, 0x00, 0x00, 0x08, 844 0x00, 0x00, 0x00, 0x08,
623 0xde, 0xad, 0xbe, 0xef, 845 0xde, 0xad, 0xbe, 0xef,
624 0xde, 0xad, 0xbe, 0xef, 846 0xde, 0xad, 0xbe, 0xef,
625 847
626 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1 848 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
627 0x00, 0x00, 0x00, 0x04, 849 0x00, 0x00, 0x00, 0x04,
628 0xde, 0xad, 0xbe, 0xef, 850 0xde, 0xad, 0xbe, 0xef,
629 851
630 0x80, 0x02, 0x00, 0x03, // RST_STREAM on Stream #1 852 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #1
631 0x00, 0x00, 0x00, 0x08, 853 0x00, 0x00, 0x00, 0x08,
632 0x00, 0x00, 0x00, 0x01, 854 0x00, 0x00, 0x00, 0x01,
633 0x00, 0x00, 0x00, 0x00, 855 0x00, 0x00, 0x00, 0x00,
634 856
635 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3 857 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
636 0x00, 0x00, 0x00, 0x00, 858 0x00, 0x00, 0x00, 0x00,
637 859
638 0x80, 0x02, 0x00, 0x03, // RST_STREAM on Stream #3 860 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #3
861 0x00, 0x00, 0x00, 0x08,
862 0x00, 0x00, 0x00, 0x03,
863 0x00, 0x00, 0x00, 0x00,
864 };
865
866 const unsigned char kV3Input[] = {
867 0x80, kVer, 0x00, 0x01, // SYN Stream #1
868 0x00, 0x00, 0x00, 0x1a,
869 0x00, 0x00, 0x00, 0x01,
870 0x00, 0x00, 0x00, 0x00,
871 0x00, 0x00, 0x00, 0x00,
872 0x00, 0x01, 0x00, 0x00,
873 0x00, 0x02, 'h', 'h',
874 0x00, 0x00, 0x00, 0x02,
875 'v', 'v',
876
877 0x80, kVer, 0x00, 0x08, // HEADERS on Stream #1
878 0x00, 0x00, 0x00, 0x22,
879 0x00, 0x00, 0x00, 0x01,
880 0x00, 0x00, 0x00, 0x00,
881 0x00, 0x02, 0x00, 0x00,
882 0x00, 0x02, 'h', '2',
883 0x00, 0x00, 0x00, 0x02,
884 'v', '2', 0x00, 0x00,
885 0x00, 0x02, 'h', '3',
886 0x00, 0x00, 0x00, 0x02,
887 'v', '3',
888
889 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
890 0x00, 0x00, 0x00, 0x0c,
891 0xde, 0xad, 0xbe, 0xef,
892 0xde, 0xad, 0xbe, 0xef,
893 0xde, 0xad, 0xbe, 0xef,
894
895 0x80, kVer, 0x00, 0x01, // SYN Stream #3
896 0x00, 0x00, 0x00, 0x0e,
897 0x00, 0x00, 0x00, 0x03,
898 0x00, 0x00, 0x00, 0x00,
899 0x00, 0x00, 0x00, 0x00,
900 0x00, 0x00,
901
902 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
903 0x00, 0x00, 0x00, 0x08,
904 0xde, 0xad, 0xbe, 0xef,
905 0xde, 0xad, 0xbe, 0xef,
906
907 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
908 0x00, 0x00, 0x00, 0x04,
909 0xde, 0xad, 0xbe, 0xef,
910
911 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #1
912 0x00, 0x00, 0x00, 0x08,
913 0x00, 0x00, 0x00, 0x01,
914 0x00, 0x00, 0x00, 0x00,
915
916 0x00, 0x00, 0x00, 0x03, // DATA on Stream #3
917 0x00, 0x00, 0x00, 0x00,
918
919 0x80, kVer, 0x00, 0x03, // RST_STREAM on Stream #3
639 0x00, 0x00, 0x00, 0x08, 920 0x00, 0x00, 0x00, 0x08,
640 0x00, 0x00, 0x00, 0x03, 921 0x00, 0x00, 0x00, 0x03,
641 0x00, 0x00, 0x00, 0x00, 922 0x00, 0x00, 0x00, 0x00,
642 }; 923 };
643 924
644 TestSpdyVisitor visitor; 925 TestSpdyVisitor visitor;
645 visitor.SimulateInFramer(input, sizeof(input)); 926 if (SPDY_VERSION_FOR_TESTS < 3) {
927 visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
928 } else {
929 visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
930 }
646 931
647 EXPECT_EQ(0, visitor.error_count_); 932 EXPECT_EQ(0, visitor.error_count_);
648 EXPECT_EQ(2, visitor.syn_frame_count_); 933 EXPECT_EQ(2, visitor.syn_frame_count_);
649 EXPECT_EQ(0, visitor.syn_reply_frame_count_); 934 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
650 EXPECT_EQ(1, visitor.headers_frame_count_); 935 EXPECT_EQ(1, visitor.headers_frame_count_);
651 EXPECT_EQ(24, visitor.data_bytes_); 936 EXPECT_EQ(24, visitor.data_bytes_);
652 EXPECT_EQ(2, visitor.fin_frame_count_); 937 EXPECT_EQ(2, visitor.fin_frame_count_);
653 EXPECT_EQ(0, visitor.fin_flag_count_); 938 EXPECT_EQ(0, visitor.fin_flag_count_);
654 EXPECT_EQ(0, visitor.zero_length_data_frame_count_); 939 EXPECT_EQ(0, visitor.zero_length_data_frame_count_);
655 EXPECT_EQ(4, visitor.data_frame_count_); 940 EXPECT_EQ(4, visitor.data_frame_count_);
656 } 941 }
657 942
658 // Test that the FIN flag on a data frame signifies EOF. 943 // Test that the FIN flag on a data frame signifies EOF.
659 TEST_F(SpdyFramerTest, FinOnDataFrame) { 944 TEST_F(SpdyFramerTest, FinOnDataFrame) {
660 const unsigned char input[] = { 945 const unsigned char kV2Input[] = {
661 0x80, 0x02, 0x00, 0x01, // SYN Stream #1 946 0x80, kVer, 0x00, 0x01, // SYN Stream #1
662 0x00, 0x00, 0x00, 0x14, 947 0x00, 0x00, 0x00, 0x14,
663 0x00, 0x00, 0x00, 0x01, 948 0x00, 0x00, 0x00, 0x01,
664 0x00, 0x00, 0x00, 0x00, 949 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x01, 950 0x00, 0x00, 0x00, 0x01,
666 0x00, 0x02, 'h', 'h', 951 0x00, 0x02, 'h', 'h',
667 0x00, 0x02, 'v', 'v', 952 0x00, 0x02, 'v', 'v',
668 953
669 0x80, 0x02, 0x00, 0x02, // SYN REPLY Stream #1 954 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
670 0x00, 0x00, 0x00, 0x10, 955 0x00, 0x00, 0x00, 0x10,
671 0x00, 0x00, 0x00, 0x01, 956 0x00, 0x00, 0x00, 0x01,
672 0x00, 0x00, 0x00, 0x01, 957 0x00, 0x00, 0x00, 0x01,
673 0x00, 0x02, 'a', 'a', 958 0x00, 0x02, 'a', 'a',
674 0x00, 0x02, 'b', 'b', 959 0x00, 0x02, 'b', 'b',
675 960
676 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1 961 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
677 0x00, 0x00, 0x00, 0x0c, 962 0x00, 0x00, 0x00, 0x0c,
678 0xde, 0xad, 0xbe, 0xef, 963 0xde, 0xad, 0xbe, 0xef,
679 0xde, 0xad, 0xbe, 0xef, 964 0xde, 0xad, 0xbe, 0xef,
680 0xde, 0xad, 0xbe, 0xef, 965 0xde, 0xad, 0xbe, 0xef,
681 966
682 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1, with EOF 967 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1, with EOF
683 0x01, 0x00, 0x00, 0x04, 968 0x01, 0x00, 0x00, 0x04,
684 0xde, 0xad, 0xbe, 0xef, 969 0xde, 0xad, 0xbe, 0xef,
685 }; 970 };
971 const unsigned char kV3Input[] = {
972 0x80, kVer, 0x00, 0x01, // SYN Stream #1
973 0x00, 0x00, 0x00, 0x1a,
974 0x00, 0x00, 0x00, 0x01,
975 0x00, 0x00, 0x00, 0x00,
976 0x00, 0x00, 0x00, 0x00,
977 0x00, 0x01, 0x00, 0x00,
978 0x00, 0x02, 'h', 'h',
979 0x00, 0x00, 0x00, 0x02,
980 'v', 'v',
981
982 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
983 0x00, 0x00, 0x00, 0x16,
984 0x00, 0x00, 0x00, 0x01,
985 0x00, 0x00, 0x00, 0x00,
986 0x00, 0x01, 0x00, 0x00,
987 0x00, 0x02, 'a', 'a',
988 0x00, 0x00, 0x00, 0x02,
989 'b', 'b',
990
991 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1
992 0x00, 0x00, 0x00, 0x0c,
993 0xde, 0xad, 0xbe, 0xef,
994 0xde, 0xad, 0xbe, 0xef,
995 0xde, 0xad, 0xbe, 0xef,
996
997 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1, with EOF
998 0x01, 0x00, 0x00, 0x04,
999 0xde, 0xad, 0xbe, 0xef,
1000 };
686 1001
687 TestSpdyVisitor visitor; 1002 TestSpdyVisitor visitor;
688 visitor.SimulateInFramer(input, sizeof(input)); 1003 if (SPDY_VERSION_FOR_TESTS < 3) {
1004 visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
1005 } else {
1006 visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
1007 }
689 1008
690 EXPECT_EQ(0, visitor.error_count_); 1009 EXPECT_EQ(0, visitor.error_count_);
691 EXPECT_EQ(1, visitor.syn_frame_count_); 1010 EXPECT_EQ(1, visitor.syn_frame_count_);
692 EXPECT_EQ(1, visitor.syn_reply_frame_count_); 1011 EXPECT_EQ(1, visitor.syn_reply_frame_count_);
693 EXPECT_EQ(0, visitor.headers_frame_count_); 1012 EXPECT_EQ(0, visitor.headers_frame_count_);
694 EXPECT_EQ(16, visitor.data_bytes_); 1013 EXPECT_EQ(16, visitor.data_bytes_);
695 EXPECT_EQ(0, visitor.fin_frame_count_); 1014 EXPECT_EQ(0, visitor.fin_frame_count_);
696 EXPECT_EQ(0, visitor.fin_flag_count_); 1015 EXPECT_EQ(0, visitor.fin_flag_count_);
697 EXPECT_EQ(1, visitor.zero_length_data_frame_count_); 1016 EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
698 EXPECT_EQ(2, visitor.data_frame_count_); 1017 EXPECT_EQ(2, visitor.data_frame_count_);
699 } 1018 }
700 1019
701 // Test that the FIN flag on a SYN reply frame signifies EOF. 1020 // Test that the FIN flag on a SYN reply frame signifies EOF.
702 TEST_F(SpdyFramerTest, FinOnSynReplyFrame) { 1021 TEST_F(SpdyFramerTest, FinOnSynReplyFrame) {
703 const unsigned char input[] = { 1022 const unsigned char kV2Input[] = {
704 0x80, 0x02, 0x00, 0x01, // SYN Stream #1 1023 0x80, kVer, 0x00, 0x01, // SYN Stream #1
705 0x00, 0x00, 0x00, 0x14, 1024 0x00, 0x00, 0x00, 0x14,
706 0x00, 0x00, 0x00, 0x01, 1025 0x00, 0x00, 0x00, 0x01,
707 0x00, 0x00, 0x00, 0x00, 1026 0x00, 0x00, 0x00, 0x00,
708 0x00, 0x00, 0x00, 0x01, 1027 0x00, 0x00, 0x00, 0x01,
709 0x00, 0x02, 'h', 'h', 1028 0x00, 0x02, 'h', 'h',
710 0x00, 0x02, 'v', 'v', 1029 0x00, 0x02, 'v', 'v',
711 1030
712 0x80, 0x02, 0x00, 0x02, // SYN REPLY Stream #1 1031 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
713 0x01, 0x00, 0x00, 0x14, 1032 0x01, 0x00, 0x00, 0x14,
714 0x00, 0x00, 0x00, 0x01, 1033 0x00, 0x00, 0x00, 0x01,
715 0x00, 0x00, 0x00, 0x00, 1034 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x01, 1035 0x00, 0x00, 0x00, 0x01,
717 0x00, 0x02, 'a', 'a', 1036 0x00, 0x02, 'a', 'a',
718 0x00, 0x02, 'b', 'b', 1037 0x00, 0x02, 'b', 'b',
719 }; 1038 };
1039 const unsigned char kV3Input[] = {
1040 0x80, kVer, 0x00, 0x01, // SYN Stream #1
1041 0x00, 0x00, 0x00, 0x1a,
1042 0x00, 0x00, 0x00, 0x01,
1043 0x00, 0x00, 0x00, 0x00,
1044 0x00, 0x00, 0x00, 0x00,
1045 0x00, 0x01, 0x00, 0x00,
1046 0x00, 0x02, 'h', 'h',
1047 0x00, 0x00, 0x00, 0x02,
1048 'v', 'v',
1049
1050 0x80, kVer, 0x00, 0x02, // SYN REPLY Stream #1
1051 0x01, 0x00, 0x00, 0x1a,
1052 0x00, 0x00, 0x00, 0x01,
1053 0x00, 0x00, 0x00, 0x00,
1054 0x00, 0x00, 0x00, 0x00,
1055 0x00, 0x01, 0x00, 0x00,
1056 0x00, 0x02, 'a', 'a',
1057 0x00, 0x00, 0x00, 0x02,
1058 'b', 'b',
1059 };
720 1060
721 TestSpdyVisitor visitor; 1061 TestSpdyVisitor visitor;
722 visitor.SimulateInFramer(input, sizeof(input)); 1062 if (SPDY_VERSION_FOR_TESTS < 3) {
1063 visitor.SimulateInFramer(kV2Input, sizeof(kV2Input));
1064 } else {
1065 visitor.SimulateInFramer(kV3Input, sizeof(kV3Input));
1066 }
723 1067
724 EXPECT_EQ(0, visitor.error_count_); 1068 EXPECT_EQ(0, visitor.error_count_);
725 EXPECT_EQ(1, visitor.syn_frame_count_); 1069 EXPECT_EQ(1, visitor.syn_frame_count_);
726 EXPECT_EQ(1, visitor.syn_reply_frame_count_); 1070 EXPECT_EQ(1, visitor.syn_reply_frame_count_);
727 EXPECT_EQ(0, visitor.headers_frame_count_); 1071 EXPECT_EQ(0, visitor.headers_frame_count_);
728 EXPECT_EQ(0, visitor.data_bytes_); 1072 EXPECT_EQ(0, visitor.data_bytes_);
729 EXPECT_EQ(0, visitor.fin_frame_count_); 1073 EXPECT_EQ(0, visitor.fin_frame_count_);
730 EXPECT_EQ(1, visitor.fin_flag_count_); 1074 EXPECT_EQ(1, visitor.fin_flag_count_);
731 EXPECT_EQ(1, visitor.zero_length_data_frame_count_); 1075 EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
732 EXPECT_EQ(0, visitor.data_frame_count_); 1076 EXPECT_EQ(0, visitor.data_frame_count_);
733 } 1077 }
734 1078
735 TEST_F(SpdyFramerTest, HeaderCompression) { 1079 TEST_F(SpdyFramerTest, HeaderCompression) {
736 SpdyFramer send_framer; 1080 SpdyFramer send_framer(kVer);
737 SpdyFramer recv_framer; 1081 SpdyFramer recv_framer(kVer);
738 1082
739 send_framer.set_enable_compression(true); 1083 send_framer.set_enable_compression(true);
740 recv_framer.set_enable_compression(true); 1084 recv_framer.set_enable_compression(true);
741 1085
742 const char kHeader1[] = "header1"; 1086 const char kHeader1[] = "header1";
743 const char kHeader2[] = "header2"; 1087 const char kHeader2[] = "header2";
744 const char kHeader3[] = "header3"; 1088 const char kHeader3[] = "header3";
745 const char kValue1[] = "value1"; 1089 const char kValue1[] = "value1";
746 const char kValue2[] = "value2"; 1090 const char kValue2[] = "value2";
747 const char kValue3[] = "value3"; 1091 const char kValue3[] = "value3";
748 1092
749 // SYN_STREAM #1 1093 // SYN_STREAM #1
750 SpdyHeaderBlock block; 1094 SpdyHeaderBlock block;
751 block[kHeader1] = kValue1; 1095 block[kHeader1] = kValue1;
752 block[kHeader2] = kValue2; 1096 block[kHeader2] = kValue2;
753 SpdyControlFlags flags(CONTROL_FLAG_NONE); 1097 SpdyControlFlags flags(CONTROL_FLAG_NONE);
754 scoped_ptr<spdy::SpdyFrame> syn_frame_1( 1098 scoped_ptr<SpdySynStreamControlFrame> syn_frame_1(
755 send_framer.CreateSynStream(1, 0, 0, flags, true, &block)); 1099 send_framer.CreateSynStream(1, 0, 0, flags, true, &block));
756 EXPECT_TRUE(syn_frame_1.get() != NULL); 1100 EXPECT_TRUE(syn_frame_1.get() != NULL);
757 1101
758 // SYN_STREAM #2 1102 // SYN_STREAM #2
759 block[kHeader3] = kValue3; 1103 block[kHeader3] = kValue3;
760 scoped_ptr<spdy::SpdyFrame> syn_frame_2( 1104 scoped_ptr<SpdySynStreamControlFrame> syn_frame_2(
761 send_framer.CreateSynStream(3, 0, 0, flags, true, &block)); 1105 send_framer.CreateSynStream(3, 0, 0, flags, true, &block));
762 EXPECT_TRUE(syn_frame_2.get() != NULL); 1106 EXPECT_TRUE(syn_frame_2.get() != NULL);
763 1107
764 // Now start decompressing 1108 // Now start decompressing
765 scoped_ptr<SpdyFrame> decompressed; 1109 scoped_ptr<SpdyFrame> decompressed;
766 scoped_ptr<SpdyFrame> decompressed_syn_frame; 1110 scoped_ptr<SpdySynStreamControlFrame> syn_frame;
767 SpdySynStreamControlFrame* syn_frame;
768 scoped_ptr<std::string> serialized_headers; 1111 scoped_ptr<std::string> serialized_headers;
769 SpdyHeaderBlock decompressed_headers; 1112 SpdyHeaderBlock decompressed_headers;
770 1113
771 // Decompress SYN_STREAM #1 1114 // Decompress SYN_STREAM #1
772 decompressed.reset(recv_framer.DecompressFrame(*syn_frame_1.get())); 1115 decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
1116 &recv_framer, *syn_frame_1.get()));
773 EXPECT_TRUE(decompressed.get() != NULL); 1117 EXPECT_TRUE(decompressed.get() != NULL);
774 EXPECT_TRUE(decompressed->is_control_frame()); 1118 EXPECT_TRUE(decompressed->is_control_frame());
775 EXPECT_EQ(SYN_STREAM, 1119 EXPECT_EQ(SYN_STREAM,
776 reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type()); 1120 reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type());
777 decompressed_syn_frame.reset( 1121 syn_frame.reset(new SpdySynStreamControlFrame(decompressed->data(), false));
778 new SpdySynStreamControlFrame(decompressed->data(), false));
779 syn_frame = reinterpret_cast<SpdySynStreamControlFrame*>(
780 decompressed_syn_frame.get());
781 serialized_headers.reset(new std::string(syn_frame->header_block(), 1122 serialized_headers.reset(new std::string(syn_frame->header_block(),
782 syn_frame->header_block_len())); 1123 syn_frame->header_block_len()));
783 EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(), 1124 EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(),
784 serialized_headers->size(), 1125 serialized_headers->size(),
785 &decompressed_headers)); 1126 &decompressed_headers));
786 EXPECT_EQ(2u, decompressed_headers.size()); 1127 EXPECT_EQ(2u, decompressed_headers.size());
787 EXPECT_EQ(kValue1, decompressed_headers[kHeader1]); 1128 EXPECT_EQ(kValue1, decompressed_headers[kHeader1]);
788 EXPECT_EQ(kValue2, decompressed_headers[kHeader2]); 1129 EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
789 1130
790 // Decompress SYN_STREAM #2 1131 // Decompress SYN_STREAM #2
791 decompressed.reset(recv_framer.DecompressFrame(*syn_frame_2.get())); 1132 decompressed.reset(SpdyFramerTestUtil::DecompressFrame(
1133 &recv_framer, *syn_frame_2.get()));
792 EXPECT_TRUE(decompressed.get() != NULL); 1134 EXPECT_TRUE(decompressed.get() != NULL);
793 EXPECT_TRUE(decompressed->is_control_frame()); 1135 EXPECT_TRUE(decompressed->is_control_frame());
794 EXPECT_EQ(SYN_STREAM, 1136 EXPECT_EQ(SYN_STREAM,
795 reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type()); 1137 reinterpret_cast<SpdyControlFrame*>(decompressed.get())->type());
796 decompressed_syn_frame.reset( 1138 syn_frame.reset(new SpdySynStreamControlFrame(decompressed->data(), false));
797 new SpdySynStreamControlFrame(decompressed->data(), false));
798 syn_frame = reinterpret_cast<SpdySynStreamControlFrame*>(
799 decompressed_syn_frame.get());
800 serialized_headers.reset(new std::string(syn_frame->header_block(), 1139 serialized_headers.reset(new std::string(syn_frame->header_block(),
801 syn_frame->header_block_len())); 1140 syn_frame->header_block_len()));
802 decompressed_headers.clear(); 1141 decompressed_headers.clear();
803 EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(), 1142 EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers->c_str(),
804 serialized_headers->size(), 1143 serialized_headers->size(),
805 &decompressed_headers)); 1144 &decompressed_headers));
806 EXPECT_EQ(3u, decompressed_headers.size()); 1145 EXPECT_EQ(3u, decompressed_headers.size());
807 EXPECT_EQ(kValue1, decompressed_headers[kHeader1]); 1146 EXPECT_EQ(kValue1, decompressed_headers[kHeader1]);
808 EXPECT_EQ(kValue2, decompressed_headers[kHeader2]); 1147 EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
809 EXPECT_EQ(kValue3, decompressed_headers[kHeader3]); 1148 EXPECT_EQ(kValue3, decompressed_headers[kHeader3]);
810 1149
811 // We didn't have data streams, so we shouldn't have (de)compressors. 1150 // We didn't have data streams, so we shouldn't have (de)compressors.
812 EXPECT_EQ(0, send_framer.num_stream_compressors()); 1151 EXPECT_EQ(0, send_framer.num_stream_compressors());
813 EXPECT_EQ(0, send_framer.num_stream_decompressors()); 1152 EXPECT_EQ(0, send_framer.num_stream_decompressors());
814 EXPECT_EQ(0, recv_framer.num_stream_compressors()); 1153 EXPECT_EQ(0, recv_framer.num_stream_compressors());
815 EXPECT_EQ(0, recv_framer.num_stream_decompressors()); 1154 EXPECT_EQ(0, recv_framer.num_stream_decompressors());
816 } 1155 }
817 1156
818 // Verify we don't leak when we leave streams unclosed 1157 // Verify we don't leak when we leave streams unclosed
819 TEST_F(SpdyFramerTest, UnclosedStreamDataCompressors) { 1158 TEST_F(SpdyFramerTest, UnclosedStreamDataCompressors) {
820 SpdyFramer send_framer; 1159 SpdyFramer send_framer(kVer);
821 1160
822 send_framer.set_enable_compression(true); 1161 send_framer.set_enable_compression(true);
823 1162
824 const char kHeader1[] = "header1"; 1163 const char kHeader1[] = "header1";
825 const char kHeader2[] = "header2"; 1164 const char kHeader2[] = "header2";
826 const char kValue1[] = "value1"; 1165 const char kValue1[] = "value1";
827 const char kValue2[] = "value2"; 1166 const char kValue2[] = "value2";
828 1167
829 SpdyHeaderBlock block; 1168 SpdyHeaderBlock block;
830 block[kHeader1] = kValue1; 1169 block[kHeader1] = kValue1;
831 block[kHeader2] = kValue2; 1170 block[kHeader2] = kValue2;
832 SpdyControlFlags flags(CONTROL_FLAG_NONE); 1171 SpdyControlFlags flags(CONTROL_FLAG_NONE);
833 scoped_ptr<spdy::SpdyFrame> syn_frame( 1172 scoped_ptr<SpdyFrame> syn_frame(
834 send_framer.CreateSynStream(1, 0, 0, flags, true, &block)); 1173 send_framer.CreateSynStream(1, 0, 0, flags, true, &block));
835 EXPECT_TRUE(syn_frame.get() != NULL); 1174 EXPECT_TRUE(syn_frame.get() != NULL);
836 1175
837 const char bytes[] = "this is a test test test test test!"; 1176 const char bytes[] = "this is a test test test test test!";
838 scoped_ptr<SpdyFrame> send_frame( 1177 scoped_ptr<SpdyFrame> send_frame(
839 send_framer.CreateDataFrame( 1178 send_framer.CreateDataFrame(
840 1, bytes, arraysize(bytes), 1179 1, bytes, arraysize(bytes),
841 DATA_FLAG_FIN)); 1180 static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
842 EXPECT_TRUE(send_frame.get() != NULL); 1181 EXPECT_TRUE(send_frame.get() != NULL);
843 1182
844 // Run the inputs through the framer. 1183 // Run the inputs through the framer.
845 TestSpdyVisitor visitor; 1184 TestSpdyVisitor visitor;
846 visitor.use_compression_ = true; 1185 visitor.use_compression_ = true;
847 const unsigned char* data; 1186 const unsigned char* data;
848 data = reinterpret_cast<const unsigned char*>(syn_frame->data()); 1187 data = reinterpret_cast<const unsigned char*>(syn_frame->data());
849 visitor.SimulateInFramer(data, syn_frame->length() + SpdyFrame::kHeaderSize); 1188 visitor.SimulateInFramer(data, syn_frame->length() + SpdyFrame::kHeaderSize);
850 data = reinterpret_cast<const unsigned char*>(send_frame->data()); 1189 data = reinterpret_cast<const unsigned char*>(send_frame->data());
851 visitor.SimulateInFramer(data, send_frame->length() + SpdyFrame::kHeaderSize); 1190 visitor.SimulateInFramer(data, send_frame->length() + SpdyFrame::kHeaderSize);
852 1191
853 EXPECT_EQ(0, visitor.error_count_); 1192 EXPECT_EQ(0, visitor.error_count_);
854 EXPECT_EQ(1, visitor.syn_frame_count_); 1193 EXPECT_EQ(1, visitor.syn_frame_count_);
855 EXPECT_EQ(0, visitor.syn_reply_frame_count_); 1194 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
856 EXPECT_EQ(0, visitor.headers_frame_count_); 1195 EXPECT_EQ(0, visitor.headers_frame_count_);
857 EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_)); 1196 EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
858 EXPECT_EQ(0, visitor.fin_frame_count_); 1197 EXPECT_EQ(0, visitor.fin_frame_count_);
859 EXPECT_EQ(0, visitor.fin_flag_count_); 1198 EXPECT_EQ(0, visitor.fin_flag_count_);
860 EXPECT_EQ(1, visitor.zero_length_data_frame_count_); 1199 EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
861 EXPECT_EQ(1, visitor.data_frame_count_); 1200 EXPECT_EQ(1, visitor.data_frame_count_);
862 1201
863 // We closed the streams, so all compressors should be down. 1202 // We closed the streams, so all compressors should be down.
864 EXPECT_EQ(0, visitor.framer_.num_stream_compressors()); 1203 EXPECT_EQ(0, visitor.framer_.num_stream_compressors());
865 EXPECT_EQ(0, visitor.framer_.num_stream_decompressors()); 1204 EXPECT_EQ(0, visitor.framer_.num_stream_decompressors());
866 EXPECT_EQ(0, send_framer.num_stream_compressors()); 1205 EXPECT_EQ(0, send_framer.num_stream_compressors());
867 EXPECT_EQ(0, send_framer.num_stream_decompressors()); 1206 EXPECT_EQ(0, send_framer.num_stream_decompressors());
868 } 1207 }
869 1208
1209 // Verify we can decompress the stream even if handed over to the
1210 // framer 1 byte at a time.
1211 TEST_F(SpdyFramerTest, UnclosedStreamDataCompressorsOneByteAtATime) {
1212 SpdyFramer send_framer(kVer);
1213
1214 send_framer.set_enable_compression(true);
1215
1216 const char kHeader1[] = "header1";
1217 const char kHeader2[] = "header2";
1218 const char kValue1[] = "value1";
1219 const char kValue2[] = "value2";
1220
1221 SpdyHeaderBlock block;
1222 block[kHeader1] = kValue1;
1223 block[kHeader2] = kValue2;
1224 SpdyControlFlags flags(CONTROL_FLAG_NONE);
1225 scoped_ptr<SpdyFrame> syn_frame(
1226 send_framer.CreateSynStream(1, 0, 0, flags, true, &block));
1227 EXPECT_TRUE(syn_frame.get() != NULL);
1228
1229 const char bytes[] = "this is a test test test test test!";
1230 scoped_ptr<SpdyFrame> send_frame(
1231 send_framer.CreateDataFrame(
1232 1, bytes, arraysize(bytes),
1233 static_cast<SpdyDataFlags>(DATA_FLAG_FIN)));
1234 EXPECT_TRUE(send_frame.get() != NULL);
1235
1236 // Run the inputs through the framer.
1237 TestSpdyVisitor visitor;
1238 visitor.use_compression_ = true;
1239 const unsigned char* data;
1240 data = reinterpret_cast<const unsigned char*>(syn_frame->data());
1241 for (size_t idx = 0;
1242 idx < syn_frame->length() + SpdyFrame::kHeaderSize;
1243 ++idx) {
1244 visitor.SimulateInFramer(data + idx, 1);
1245 ASSERT_EQ(0, visitor.error_count_);
1246 }
1247 data = reinterpret_cast<const unsigned char*>(send_frame->data());
1248 for (size_t idx = 0;
1249 idx < send_frame->length() + SpdyFrame::kHeaderSize;
1250 ++idx) {
1251 visitor.SimulateInFramer(data + idx, 1);
1252 ASSERT_EQ(0, visitor.error_count_);
1253 }
1254
1255 EXPECT_EQ(0, visitor.error_count_);
1256 EXPECT_EQ(1, visitor.syn_frame_count_);
1257 EXPECT_EQ(0, visitor.syn_reply_frame_count_);
1258 EXPECT_EQ(0, visitor.headers_frame_count_);
1259 EXPECT_EQ(arraysize(bytes), static_cast<unsigned>(visitor.data_bytes_));
1260 EXPECT_EQ(0, visitor.fin_frame_count_);
1261 EXPECT_EQ(0, visitor.fin_flag_count_);
1262 EXPECT_EQ(1, visitor.zero_length_data_frame_count_);
1263 EXPECT_EQ(1, visitor.data_frame_count_);
1264
1265 // We closed the streams, so all compressors should be down.
1266 EXPECT_EQ(0, visitor.framer_.num_stream_compressors());
1267 EXPECT_EQ(0, visitor.framer_.num_stream_decompressors());
1268 EXPECT_EQ(0, send_framer.num_stream_compressors());
1269 EXPECT_EQ(0, send_framer.num_stream_decompressors());
1270 }
1271
870 TEST_F(SpdyFramerTest, WindowUpdateFrame) { 1272 TEST_F(SpdyFramerTest, WindowUpdateFrame) {
1273 SpdyFramer framer(kVer);
871 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame( 1274 scoped_ptr<SpdyWindowUpdateControlFrame> window_update_frame(
872 SpdyFramer::CreateWindowUpdate(1, 0x12345678)); 1275 framer.CreateWindowUpdate(1, 0x12345678));
873 1276
874 const unsigned char expected_data_frame[] = { 1277 const unsigned char expected_data_frame[] = {
875 0x80, 0x02, 0x00, 0x09, 1278 0x80, kVer, 0x00, 0x09,
876 0x00, 0x00, 0x00, 0x08, 1279 0x00, 0x00, 0x00, 0x08,
877 0x00, 0x00, 0x00, 0x01, 1280 0x00, 0x00, 0x00, 0x01,
878 0x12, 0x34, 0x56, 0x78 1281 0x12, 0x34, 0x56, 0x78
879 }; 1282 };
880 1283
881 EXPECT_EQ(16u, window_update_frame->size()); 1284 EXPECT_EQ(16u, window_update_frame->size());
882 EXPECT_EQ(0, 1285 EXPECT_EQ(0,
883 memcmp(window_update_frame->data(), expected_data_frame, 16)); 1286 memcmp(window_update_frame->data(), expected_data_frame, 16));
884 } 1287 }
885 1288
886 TEST_F(SpdyFramerTest, CreateDataFrame) { 1289 TEST_F(SpdyFramerTest, CreateDataFrame) {
887 SpdyFramer framer; 1290 SpdyFramer framer(kVer);
888 1291
889 { 1292 {
890 const char kDescription[] = "'hello' data frame, no FIN"; 1293 const char kDescription[] = "'hello' data frame, no FIN";
891 const unsigned char kFrameData[] = { 1294 const unsigned char kFrameData[] = {
892 0x00, 0x00, 0x00, 0x01, 1295 0x00, 0x00, 0x00, 0x01,
893 0x00, 0x00, 0x00, 0x05, 1296 0x00, 0x00, 0x00, 0x05,
894 'h', 'e', 'l', 'l', 1297 'h', 'e', 'l', 'l',
895 'o' 1298 'o'
896 }; 1299 };
897 scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame( 1300 scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 memcpy(expected_frame_data.get(), kFrameHeader, arraysize(kFrameHeader)); 1366 memcpy(expected_frame_data.get(), kFrameHeader, arraysize(kFrameHeader));
964 memset(expected_frame_data.get() + arraysize(kFrameHeader), 'A', kDataSize); 1367 memset(expected_frame_data.get() + arraysize(kFrameHeader), 'A', kDataSize);
965 1368
966 scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame( 1369 scoped_ptr<SpdyFrame> frame(framer.CreateDataFrame(
967 1, kData.data(), kData.size(), DATA_FLAG_FIN)); 1370 1, kData.data(), kData.size(), DATA_FLAG_FIN));
968 CompareFrame(kDescription, *frame, expected_frame_data.get(), kFrameSize); 1371 CompareFrame(kDescription, *frame, expected_frame_data.get(), kFrameSize);
969 } 1372 }
970 } 1373 }
971 1374
972 TEST_F(SpdyFramerTest, CreateSynStreamUncompressed) { 1375 TEST_F(SpdyFramerTest, CreateSynStreamUncompressed) {
973 SpdyFramer framer; 1376 SpdyFramer framer(kVer);
974 framer.set_enable_compression(false); 1377 framer.set_enable_compression(false);
975 1378
976 { 1379 {
977 const char kDescription[] = "SYN_STREAM frame, lowest pri, no FIN"; 1380 const char kDescription[] = "SYN_STREAM frame, lowest pri, no FIN";
978 1381
979 SpdyHeaderBlock headers; 1382 SpdyHeaderBlock headers;
980 headers["bar"] = "foo"; 1383 headers["bar"] = "foo";
981 headers["foo"] = "bar"; 1384 headers["foo"] = "bar";
982 1385
983 const unsigned char kFrameData[] = { 1386 const unsigned char kPri =
984 0x80, 0x02, 0x00, 0x01, 1387 (SPDY_VERSION_FOR_TESTS != 2) ? 0xE0 : 0xC0;
1388 const unsigned char kV2FrameData[] = {
1389 0x80, kVer, 0x00, 0x01,
985 0x00, 0x00, 0x00, 0x20, 1390 0x00, 0x00, 0x00, 0x20,
986 0x00, 0x00, 0x00, 0x01, 1391 0x00, 0x00, 0x00, 0x01,
987 0x00, 0x00, 0x00, 0x00, 1392 0x00, 0x00, 0x00, 0x00,
988 0xC0, 0x00, 0x00, 0x02, 1393 kPri, 0x00, 0x00, 0x02,
989 0x00, 0x03, 'b', 'a', 1394 0x00, 0x03, 'b', 'a',
990 'r', 0x00, 0x03, 'f', 1395 'r', 0x00, 0x03, 'f',
991 'o', 'o', 0x00, 0x03, 1396 'o', 'o', 0x00, 0x03,
992 'f', 'o', 'o', 0x00, 1397 'f', 'o', 'o', 0x00,
993 0x03, 'b', 'a', 'r' 1398 0x03, 'b', 'a', 'r'
994 }; 1399 };
995 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream( 1400 const unsigned char kV3FrameData[] = {
996 1, 0, SPDY_PRIORITY_LOWEST, CONTROL_FLAG_NONE, 1401 0x80, kVer, 0x00, 0x01,
997 false, &headers)); 1402 0x00, 0x00, 0x00, 0x2a,
998 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1403 0x00, 0x00, 0x00, 0x01,
999 EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId( 1404 0x00, 0x00, 0x00, 0x00,
1000 reinterpret_cast<const SpdyControlFrame*>(frame.get()))); 1405 kPri, 0x00, 0x00, 0x00,
1406 0x00, 0x02, 0x00, 0x00,
1407 0x00, 0x03, 'b', 'a',
1408 'r', 0x00, 0x00, 0x00,
1409 0x03, 'f', 'o', 'o',
1410 0x00, 0x00, 0x00, 0x03,
1411 'f', 'o', 'o', 0x00,
1412 0x00, 0x00, 0x03, 'b',
1413 'a', 'r'
1414 };
1415 scoped_ptr<SpdySynStreamControlFrame> frame(framer.CreateSynStream(
1416 1, 0, framer.GetLowestPriority(), CONTROL_FLAG_NONE, false, &headers));
1417 CompareFrame(kDescription,
1418 *frame,
1419 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1420 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1421 : arraysize(kV3FrameData));
1422 EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
1001 } 1423 }
1002 1424
1003 { 1425 {
1004 const char kDescription[] = 1426 const char kDescription[] =
1005 "SYN_STREAM frame with a 0-length header name, highest pri, FIN, " 1427 "SYN_STREAM frame with a 0-length header name, highest pri, FIN, "
1006 "max stream ID"; 1428 "max stream ID";
1007 1429
1008 SpdyHeaderBlock headers; 1430 SpdyHeaderBlock headers;
1009 headers[""] = "foo"; 1431 headers[""] = "foo";
1010 headers["foo"] = "bar"; 1432 headers["foo"] = "bar";
1011 1433
1012 const unsigned char kFrameData[] = { 1434 const unsigned char kV2FrameData[] = {
1013 0x80, 0x02, 0x00, 0x01, 1435 0x80, kVer, 0x00, 0x01,
1014 0x01, 0x00, 0x00, 0x1D, 1436 0x01, 0x00, 0x00, 0x1D,
1015 0x7f, 0xff, 0xff, 0xff, 1437 0x7f, 0xff, 0xff, 0xff,
1016 0x7f, 0xff, 0xff, 0xff, 1438 0x7f, 0xff, 0xff, 0xff,
1017 0x00, 0x00, 0x00, 0x02, 1439 0x00, 0x00, 0x00, 0x02,
1018 0x00, 0x00, 0x00, 0x03, 1440 0x00, 0x00, 0x00, 0x03,
1019 'f', 'o', 'o', 0x00, 1441 'f', 'o', 'o', 0x00,
1020 0x03, 'f', 'o', 'o', 1442 0x03, 'f', 'o', 'o',
1021 0x00, 0x03, 'b', 'a', 1443 0x00, 0x03, 'b', 'a',
1022 'r' 1444 'r'
1023 }; 1445 };
1446 const unsigned char kV3FrameData[] = {
1447 0x80, kVer, 0x00, 0x01,
1448 0x01, 0x00, 0x00, 0x27,
1449 0x7f, 0xff, 0xff, 0xff,
1450 0x7f, 0xff, 0xff, 0xff,
1451 0x00, 0x00, 0x00, 0x00,
1452 0x00, 0x02, 0x00, 0x00,
1453 0x00, 0x00, 0x00, 0x00,
1454 0x00, 0x03, 'f', 'o',
1455 'o', 0x00, 0x00, 0x00,
1456 0x03, 'f', 'o', 'o',
1457 0x00, 0x00, 0x00, 0x03,
1458 'b', 'a', 'r'
1459 };
1024 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream( 1460 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
1025 0x7fffffff, 0x7fffffff, SPDY_PRIORITY_HIGHEST, CONTROL_FLAG_FIN, 1461 0x7fffffff, 0x7fffffff, framer.GetHighestPriority(), CONTROL_FLAG_FIN,
1026 false, &headers)); 1462 false, &headers));
1027 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1463 CompareFrame(kDescription,
1464 *frame,
1465 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1466 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1467 : arraysize(kV3FrameData));
1028 } 1468 }
1029 1469
1030 { 1470 {
1031 const char kDescription[] = 1471 const char kDescription[] =
1032 "SYN_STREAM frame with a 0-length header val, highest pri, FIN, " 1472 "SYN_STREAM frame with a 0-length header val, high pri, FIN, "
1033 "max stream ID"; 1473 "max stream ID";
1034 1474
1035 SpdyHeaderBlock headers; 1475 SpdyHeaderBlock headers;
1036 headers["bar"] = "foo"; 1476 headers["bar"] = "foo";
1037 headers["foo"] = ""; 1477 headers["foo"] = "";
1038 1478
1039 const unsigned char kFrameData[] = { 1479 const unsigned char kPri =
1040 0x80, 0x02, 0x00, 0x01, 1480 (SPDY_VERSION_FOR_TESTS != 2) ? 0x20 : 0x40;
1481 const unsigned char kV2FrameData[] = {
1482 0x80, kVer, 0x00, 0x01,
1041 0x01, 0x00, 0x00, 0x1D, 1483 0x01, 0x00, 0x00, 0x1D,
1042 0x7f, 0xff, 0xff, 0xff, 1484 0x7f, 0xff, 0xff, 0xff,
1043 0x7f, 0xff, 0xff, 0xff, 1485 0x7f, 0xff, 0xff, 0xff,
1044 0x00, 0x00, 0x00, 0x02, 1486 kPri, 0x00, 0x00, 0x02,
1045 0x00, 0x03, 'b', 'a', 1487 0x00, 0x03, 'b', 'a',
1046 'r', 0x00, 0x03, 'f', 1488 'r', 0x00, 0x03, 'f',
1047 'o', 'o', 0x00, 0x03, 1489 'o', 'o', 0x00, 0x03,
1048 'f', 'o', 'o', 0x00, 1490 'f', 'o', 'o', 0x00,
1049 0x00 1491 0x00
1050 }; 1492 };
1493 const unsigned char kV3FrameData[] = {
1494 0x80, kVer, 0x00, 0x01,
1495 0x01, 0x00, 0x00, 0x27,
1496 0x7f, 0xff, 0xff, 0xff,
1497 0x7f, 0xff, 0xff, 0xff,
1498 kPri, 0x00, 0x00, 0x00,
1499 0x00, 0x02, 0x00, 0x00,
1500 0x00, 0x03, 'b', 'a',
1501 'r', 0x00, 0x00, 0x00,
1502 0x03, 'f', 'o', 'o',
1503 0x00, 0x00, 0x00, 0x03,
1504 'f', 'o', 'o', 0x00,
1505 0x00, 0x00, 0x00
1506 };
1051 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream( 1507 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
1052 0x7fffffff, 0x7fffffff, SPDY_PRIORITY_HIGHEST, CONTROL_FLAG_FIN, 1508 0x7fffffff, 0x7fffffff, 1, CONTROL_FLAG_FIN, false, &headers));
1053 false, &headers)); 1509 CompareFrame(kDescription,
1054 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1510 *frame,
1511 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1512 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1513 : arraysize(kV3FrameData));
1055 } 1514 }
1056 } 1515 }
1057 1516
1058 TEST_F(SpdyFramerTest, CreateSynStreamCompressed) { 1517 TEST_F(SpdyFramerTest, CreateSynStreamCompressed) {
1059 SpdyFramer framer; 1518 SpdyFramer framer(kVer);
1060 framer.set_enable_compression(true); 1519 framer.set_enable_compression(true);
1061 1520
1062 { 1521 {
1063 const char kDescription[] = 1522 const char kDescription[] =
1064 "SYN_STREAM frame, lowest pri, no FIN"; 1523 "SYN_STREAM frame, low pri, no FIN";
1065 1524
1066 SpdyHeaderBlock headers; 1525 SpdyHeaderBlock headers;
1067 headers["bar"] = "foo"; 1526 headers["bar"] = "foo";
1068 headers["foo"] = "bar"; 1527 headers["foo"] = "bar";
1069 1528
1070 const unsigned char kFrameData[] = { 1529 const SpdyPriority priority =
1071 0x80, 0x02, 0x00, 0x01, 1530 (SPDY_VERSION_FOR_TESTS != 2) ? 4 : 2;
1531 const unsigned char kV2FrameData[] = {
1532 0x80, kVer, 0x00, 0x01,
1072 0x00, 0x00, 0x00, 0x25, 1533 0x00, 0x00, 0x00, 0x25,
1073 0x00, 0x00, 0x00, 0x01, 1534 0x00, 0x00, 0x00, 0x01,
1074 0x00, 0x00, 0x00, 0x00, 1535 0x00, 0x00, 0x00, 0x00,
1075 0xC0, 0x00, 0x38, 0xea, 1536 0x80, 0x00, 0x38, 0xea,
1076 0xdf, 0xa2, 0x51, 0xb2, 1537 0xdf, 0xa2, 0x51, 0xb2,
1077 0x62, 0x60, 0x62, 0x60, 1538 0x62, 0x60, 0x62, 0x60,
1078 0x4e, 0x4a, 0x2c, 0x62, 1539 0x4e, 0x4a, 0x2c, 0x62,
1079 0x60, 0x4e, 0xcb, 0xcf, 1540 0x60, 0x4e, 0xcb, 0xcf,
1080 0x87, 0x12, 0x40, 0x2e, 1541 0x87, 0x12, 0x40, 0x2e,
1081 0x00, 0x00, 0x00, 0xff, 1542 0x00, 0x00, 0x00, 0xff,
1082 0xff 1543 0xff
1083 }; 1544 };
1545 const unsigned char kV3FrameData[] = {
1546 0x80, kVer, 0x00, 0x01,
1547 0x00, 0x00, 0x00, 0x27,
1548 0x00, 0x00, 0x00, 0x01,
1549 0x00, 0x00, 0x00, 0x00,
1550 0x80, 0x00, 0x38, 0xEA,
1551 0xE3, 0xC6, 0xA7, 0xC2,
1552 0x02, 0xE5, 0x0E, 0x50,
1553 0xC2, 0x4B, 0x4A, 0x04,
1554 0xE5, 0x0B, 0xE6, 0xB4,
1555 0xFC, 0x7C, 0x24, 0x0A,
1556 0x28, 0x08, 0x00, 0x00,
1557 0x00, 0xFF, 0xFF
1558 };
1084 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream( 1559 scoped_ptr<SpdyFrame> frame(framer.CreateSynStream(
1085 1, 0, SPDY_PRIORITY_LOWEST, CONTROL_FLAG_NONE, 1560 1, 0, priority, CONTROL_FLAG_NONE, true, &headers));
1086 true, &headers)); 1561 CompareFrame(kDescription,
1087 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1562 *frame,
1563 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1564 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1565 : arraysize(kV3FrameData));
1088 } 1566 }
1089 } 1567 }
1090 1568
1091 TEST_F(SpdyFramerTest, CreateSynReplyUncompressed) { 1569 TEST_F(SpdyFramerTest, CreateSynReplyUncompressed) {
1092 SpdyFramer framer; 1570 SpdyFramer framer(kVer);
1093 framer.set_enable_compression(false); 1571 framer.set_enable_compression(false);
1094 1572
1095 { 1573 {
1096 const char kDescription[] = "SYN_REPLY frame, no FIN"; 1574 const char kDescription[] = "SYN_REPLY frame, no FIN";
1097 1575
1098 SpdyHeaderBlock headers; 1576 SpdyHeaderBlock headers;
1099 headers["bar"] = "foo"; 1577 headers["bar"] = "foo";
1100 headers["foo"] = "bar"; 1578 headers["foo"] = "bar";
1101 1579
1102 const unsigned char kFrameData[] = { 1580 const unsigned char kV2FrameData[] = {
1103 0x80, 0x02, 0x00, 0x02, 1581 0x80, kVer, 0x00, 0x02,
1104 0x00, 0x00, 0x00, 0x1C, 1582 0x00, 0x00, 0x00, 0x1C,
1105 0x00, 0x00, 0x00, 0x01, 1583 0x00, 0x00, 0x00, 0x01,
1106 0x00, 0x00, 0x00, 0x02, 1584 0x00, 0x00, 0x00, 0x02,
1107 0x00, 0x03, 'b', 'a', 1585 0x00, 0x03, 'b', 'a',
1108 'r', 0x00, 0x03, 'f', 1586 'r', 0x00, 0x03, 'f',
1109 'o', 'o', 0x00, 0x03, 1587 'o', 'o', 0x00, 0x03,
1110 'f', 'o', 'o', 0x00, 1588 'f', 'o', 'o', 0x00,
1111 0x03, 'b', 'a', 'r' 1589 0x03, 'b', 'a', 'r'
1112 }; 1590 };
1591 const unsigned char kV3FrameData[] = {
1592 0x80, kVer, 0x00, 0x02,
1593 0x00, 0x00, 0x00, 0x24,
1594 0x00, 0x00, 0x00, 0x01,
1595 0x00, 0x00, 0x00, 0x02,
1596 0x00, 0x00, 0x00, 0x03,
1597 'b', 'a', 'r', 0x00,
1598 0x00, 0x00, 0x03, 'f',
1599 'o', 'o', 0x00, 0x00,
1600 0x00, 0x03, 'f', 'o',
1601 'o', 0x00, 0x00, 0x00,
1602 0x03, 'b', 'a', 'r'
1603 };
1113 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply( 1604 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1114 1, CONTROL_FLAG_NONE, false, &headers)); 1605 1, CONTROL_FLAG_NONE, false, &headers));
1115 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1606 CompareFrame(kDescription,
1607 *frame,
1608 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1609 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1610 : arraysize(kV3FrameData));
1116 } 1611 }
1117 1612
1118 { 1613 {
1119 const char kDescription[] = 1614 const char kDescription[] =
1120 "SYN_REPLY frame with a 0-length header name, FIN, max stream ID"; 1615 "SYN_REPLY frame with a 0-length header name, FIN, max stream ID";
1121 1616
1122 SpdyHeaderBlock headers; 1617 SpdyHeaderBlock headers;
1123 headers[""] = "foo"; 1618 headers[""] = "foo";
1124 headers["foo"] = "bar"; 1619 headers["foo"] = "bar";
1125 1620
1126 const unsigned char kFrameData[] = { 1621 const unsigned char kV2FrameData[] = {
1127 0x80, 0x02, 0x00, 0x02, 1622 0x80, kVer, 0x00, 0x02,
1128 0x01, 0x00, 0x00, 0x19, 1623 0x01, 0x00, 0x00, 0x19,
1129 0x7f, 0xff, 0xff, 0xff, 1624 0x7f, 0xff, 0xff, 0xff,
1130 0x00, 0x00, 0x00, 0x02, 1625 0x00, 0x00, 0x00, 0x02,
1131 0x00, 0x00, 0x00, 0x03, 1626 0x00, 0x00, 0x00, 0x03,
1132 'f', 'o', 'o', 0x00, 1627 'f', 'o', 'o', 0x00,
1133 0x03, 'f', 'o', 'o', 1628 0x03, 'f', 'o', 'o',
1134 0x00, 0x03, 'b', 'a', 1629 0x00, 0x03, 'b', 'a',
1135 'r' 1630 'r'
1136 }; 1631 };
1632 const unsigned char kV3FrameData[] = {
1633 0x80, kVer, 0x00, 0x02,
1634 0x01, 0x00, 0x00, 0x21,
1635 0x7f, 0xff, 0xff, 0xff,
1636 0x00, 0x00, 0x00, 0x02,
1637 0x00, 0x00, 0x00, 0x00,
1638 0x00, 0x00, 0x00, 0x03,
1639 'f', 'o', 'o', 0x00,
1640 0x00, 0x00, 0x03, 'f',
1641 'o', 'o', 0x00, 0x00,
1642 0x00, 0x03, 'b', 'a',
1643 'r'
1644 };
1137 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply( 1645 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1138 0x7fffffff, CONTROL_FLAG_FIN, false, &headers)); 1646 0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
1139 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1647 CompareFrame(kDescription,
1648 *frame,
1649 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1650 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1651 : arraysize(kV3FrameData));
1140 } 1652 }
1141 1653
1142 { 1654 {
1143 const char kDescription[] = 1655 const char kDescription[] =
1144 "SYN_REPLY frame with a 0-length header val, FIN, max stream ID"; 1656 "SYN_REPLY frame with a 0-length header val, FIN, max stream ID";
1145 1657
1146 SpdyHeaderBlock headers; 1658 SpdyHeaderBlock headers;
1147 headers["bar"] = "foo"; 1659 headers["bar"] = "foo";
1148 headers["foo"] = ""; 1660 headers["foo"] = "";
1149 1661
1150 const unsigned char kFrameData[] = { 1662 const unsigned char kV2FrameData[] = {
1151 0x80, 0x02, 0x00, 0x02, 1663 0x80, kVer, 0x00, 0x02,
1152 0x01, 0x00, 0x00, 0x19, 1664 0x01, 0x00, 0x00, 0x19,
1153 0x7f, 0xff, 0xff, 0xff, 1665 0x7f, 0xff, 0xff, 0xff,
1154 0x00, 0x00, 0x00, 0x02, 1666 0x00, 0x00, 0x00, 0x02,
1155 0x00, 0x03, 'b', 'a', 1667 0x00, 0x03, 'b', 'a',
1156 'r', 0x00, 0x03, 'f', 1668 'r', 0x00, 0x03, 'f',
1157 'o', 'o', 0x00, 0x03, 1669 'o', 'o', 0x00, 0x03,
1158 'f', 'o', 'o', 0x00, 1670 'f', 'o', 'o', 0x00,
1159 0x00 1671 0x00
1160 }; 1672 };
1673 const unsigned char kV3FrameData[] = {
1674 0x80, kVer, 0x00, 0x02,
1675 0x01, 0x00, 0x00, 0x21,
1676 0x7f, 0xff, 0xff, 0xff,
1677 0x00, 0x00, 0x00, 0x02,
1678 0x00, 0x00, 0x00, 0x03,
1679 'b', 'a', 'r', 0x00,
1680 0x00, 0x00, 0x03, 'f',
1681 'o', 'o', 0x00, 0x00,
1682 0x00, 0x03, 'f', 'o',
1683 'o', 0x00, 0x00, 0x00,
1684 0x00
1685 };
1161 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply( 1686 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1162 0x7fffffff, CONTROL_FLAG_FIN, false, &headers)); 1687 0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
1163 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1688 CompareFrame(kDescription,
1689 *frame,
1690 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1691 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1692 : arraysize(kV3FrameData));
1164 } 1693 }
1165 } 1694 }
1166 1695
1167 TEST_F(SpdyFramerTest, CreateSynReplyCompressed) { 1696 TEST_F(SpdyFramerTest, CreateSynReplyCompressed) {
1168 SpdyFramer framer; 1697 SpdyFramer framer(kVer);
1169 framer.set_enable_compression(true); 1698 framer.set_enable_compression(true);
1170 1699
1171 { 1700 {
1172 const char kDescription[] = "SYN_REPLY frame, no FIN"; 1701 const char kDescription[] = "SYN_REPLY frame, no FIN";
1173 1702
1174 SpdyHeaderBlock headers; 1703 SpdyHeaderBlock headers;
1175 headers["bar"] = "foo"; 1704 headers["bar"] = "foo";
1176 headers["foo"] = "bar"; 1705 headers["foo"] = "bar";
1177 1706
1178 const unsigned char kFrameData[] = { 1707 const unsigned char kV2FrameData[] = {
1179 0x80, 0x02, 0x00, 0x02, 1708 0x80, kVer, 0x00, 0x02,
1180 0x00, 0x00, 0x00, 0x21, 1709 0x00, 0x00, 0x00, 0x21,
1181 0x00, 0x00, 0x00, 0x01, 1710 0x00, 0x00, 0x00, 0x01,
1182 0x00, 0x00, 0x38, 0xea, 1711 0x00, 0x00, 0x38, 0xea,
1183 0xdf, 0xa2, 0x51, 0xb2, 1712 0xdf, 0xa2, 0x51, 0xb2,
1184 0x62, 0x60, 0x62, 0x60, 1713 0x62, 0x60, 0x62, 0x60,
1185 0x4e, 0x4a, 0x2c, 0x62, 1714 0x4e, 0x4a, 0x2c, 0x62,
1186 0x60, 0x4e, 0xcb, 0xcf, 1715 0x60, 0x4e, 0xcb, 0xcf,
1187 0x87, 0x12, 0x40, 0x2e, 1716 0x87, 0x12, 0x40, 0x2e,
1188 0x00, 0x00, 0x00, 0xff, 1717 0x00, 0x00, 0x00, 0xff,
1189 0xff 1718 0xff
1190 }; 1719 };
1720 const unsigned char kV3FrameData[] = {
1721 0x80, kVer, 0x00, 0x02,
1722 0x00, 0x00, 0x00, 0x21,
1723 0x00, 0x00, 0x00, 0x01,
1724 0x38, 0xea, 0xe3, 0xc6,
1725 0xa7, 0xc2, 0x02, 0xe5,
1726 0x0e, 0x50, 0xc2, 0x4b,
1727 0x4a, 0x04, 0xe5, 0x0b,
1728 0xe6, 0xb4, 0xfc, 0x7c,
1729 0x24, 0x0a, 0x28, 0x08,
1730 0x00, 0x00, 0x00, 0xff,
1731 0xff
1732 };
1191 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply( 1733 scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1192 1, CONTROL_FLAG_NONE, true, &headers)); 1734 1, CONTROL_FLAG_NONE, true, &headers));
1193 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1735 CompareFrame(kDescription,
1736 *frame,
1737 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1738 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1739 : arraysize(kV3FrameData));
1194 } 1740 }
1195 } 1741 }
1196 1742
1197 TEST_F(SpdyFramerTest, CreateRstStream) { 1743 TEST_F(SpdyFramerTest, CreateRstStream) {
1198 SpdyFramer framer; 1744 SpdyFramer framer(kVer);
1199 1745
1200 { 1746 {
1201 const char kDescription[] = "RST_STREAM frame"; 1747 const char kDescription[] = "RST_STREAM frame";
1202 const unsigned char kFrameData[] = { 1748 const unsigned char kFrameData[] = {
1203 0x80, 0x02, 0x00, 0x03, 1749 0x80, kVer, 0x00, 0x03,
1204 0x00, 0x00, 0x00, 0x08, 1750 0x00, 0x00, 0x00, 0x08,
1205 0x00, 0x00, 0x00, 0x01, 1751 0x00, 0x00, 0x00, 0x01,
1206 0x00, 0x00, 0x00, 0x01, 1752 0x00, 0x00, 0x00, 0x01,
1207 }; 1753 };
1208 scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(1, PROTOCOL_ERROR)); 1754 scoped_ptr<SpdyRstStreamControlFrame> frame(
1755 framer.CreateRstStream(1, PROTOCOL_ERROR));
1209 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1756 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1210 EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId( 1757 EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
1211 reinterpret_cast<const SpdyControlFrame*>(frame.get())));
1212 } 1758 }
1213 1759
1214 { 1760 {
1215 const char kDescription[] = "RST_STREAM frame with max stream ID"; 1761 const char kDescription[] = "RST_STREAM frame with max stream ID";
1216 const unsigned char kFrameData[] = { 1762 const unsigned char kFrameData[] = {
1217 0x80, 0x02, 0x00, 0x03, 1763 0x80, kVer, 0x00, 0x03,
1218 0x00, 0x00, 0x00, 0x08, 1764 0x00, 0x00, 0x00, 0x08,
1219 0x7f, 0xff, 0xff, 0xff, 1765 0x7f, 0xff, 0xff, 0xff,
1220 0x00, 0x00, 0x00, 0x01, 1766 0x00, 0x00, 0x00, 0x01,
1221 }; 1767 };
1222 scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(0x7FFFFFFF, 1768 scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(0x7FFFFFFF,
1223 PROTOCOL_ERROR)); 1769 PROTOCOL_ERROR));
1224 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1770 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1225 } 1771 }
1226 1772
1227 { 1773 {
1228 const char kDescription[] = "RST_STREAM frame with max status code"; 1774 const char kDescription[] = "RST_STREAM frame with max status code";
1229 const unsigned char kFrameData[] = { 1775 const unsigned char kFrameData[] = {
1230 0x80, 0x02, 0x00, 0x03, 1776 0x80, kVer, 0x00, 0x03,
1231 0x00, 0x00, 0x00, 0x08, 1777 0x00, 0x00, 0x00, 0x08,
1232 0x7f, 0xff, 0xff, 0xff, 1778 0x7f, 0xff, 0xff, 0xff,
1233 0x00, 0x00, 0x00, 0x06, 1779 0x00, 0x00, 0x00, 0x06,
1234 }; 1780 };
1235 scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(0x7FFFFFFF, 1781 scoped_ptr<SpdyFrame> frame(framer.CreateRstStream(0x7FFFFFFF,
1236 INTERNAL_ERROR)); 1782 INTERNAL_ERROR));
1237 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1783 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1238 } 1784 }
1239 } 1785 }
1240 1786
1241 TEST_F(SpdyFramerTest, CreateSettings) { 1787 TEST_F(SpdyFramerTest, CreateSettings) {
1242 SpdyFramer framer; 1788 SpdyFramer framer(kVer);
1789
1790 {
1791 const char kDescription[] = "Network byte order SETTINGS frame";
1792
1793 uint32 kValue = 0x0a0b0c0d;
1794 uint8 kFlags = 0x04;
1795 uint32 kId = 0x030201;
1796 SettingsFlagsAndId idAndFlags(kFlags, kId);
1797
1798 SpdySettings settings;
1799 settings.push_back(SpdySetting(idAndFlags, kValue));
1800
1801 EXPECT_EQ(kValue, settings.back().second);
1802 EXPECT_EQ(kFlags, settings.back().first.flags());
1803 EXPECT_EQ(kId, settings.back().first.id());
1804
1805 const unsigned char kFrameDatav2[] = {
1806 0x80, kVer, 0x00, 0x04,
1807 0x00, 0x00, 0x00, 0x0c,
1808 0x00, 0x00, 0x00, 0x01,
1809 0x01, 0x02, 0x03, 0x04,
1810 0x0a, 0x0b, 0x0c, 0x0d,
1811 };
1812
1813 const unsigned char kFrameDatav3[] = {
1814 0x80, kVer, 0x00, 0x04,
1815 0x00, 0x00, 0x00, 0x0c,
1816 0x00, 0x00, 0x00, 0x01,
1817 0x04, 0x03, 0x02, 0x01,
1818 0x0a, 0x0b, 0x0c, 0x0d,
1819 };
1820
1821 scoped_ptr<SpdySettingsControlFrame> frame(framer.CreateSettings(settings));
1822 CompareFrame(kDescription,
1823 *frame,
1824 (SPDY_VERSION_FOR_TESTS < 3) ? kFrameDatav2 : kFrameDatav3,
1825 arraysize(kFrameDatav3)); // Size is unchanged among versions.
1826 EXPECT_EQ(SpdyFramer::kInvalidStream,
1827 SpdyFramer::GetControlFrameStreamId(frame.get()));
1828
1829 // Make sure that ParseSettings also works as advertised.
1830 SpdySettings parsed_settings;
1831 EXPECT_TRUE(framer.ParseSettings(frame.get(), &parsed_settings));
1832 EXPECT_EQ(settings.size(), parsed_settings.size());
1833 EXPECT_EQ(kFlags, parsed_settings.back().first.flags());
1834 EXPECT_EQ(kId, parsed_settings.back().first.id());
1835 }
1243 1836
1244 { 1837 {
1245 const char kDescription[] = "Basic SETTINGS frame"; 1838 const char kDescription[] = "Basic SETTINGS frame";
1246 1839
1247 SpdySettings settings; 1840 SpdySettings settings;
1248 settings.push_back(SpdySetting(0x00000000, 0x00000000)); 1841 settings.push_back(
1249 settings.push_back(SpdySetting(0xffffffff, 0x00000001)); 1842 SpdySettingFromWireFormat(0x00000000, 0x00000000)); // 1st Setting
1250 settings.push_back(SpdySetting(0xff000001, 0x00000002)); 1843 settings.push_back(
1844 SpdySettingFromWireFormat(0xffffffff, 0x00000001)); // 2nd Setting
1845 settings.push_back(
1846 SpdySettingFromWireFormat(0xff000001, 0x00000002)); // 3rd Setting
1251 1847
1252 // Duplicates allowed 1848 // Duplicates allowed
1253 settings.push_back(SpdySetting(0x01000002, 0x00000003)); 1849 settings.push_back(
1254 settings.push_back(SpdySetting(0x01000002, 0x00000003)); 1850 SpdySettingFromWireFormat(0x01000002, 0x00000003)); // 4th Setting
1851 settings.push_back(
1852 SpdySettingFromWireFormat(0x01000002, 0x00000003)); // 5th Setting
1255 1853
1256 settings.push_back(SpdySetting(0x01000003, 0x000000ff)); 1854 settings.push_back(
1257 settings.push_back(SpdySetting(0x01000004, 0xff000001)); 1855 SpdySettingFromWireFormat(0x01000003, 0x000000ff)); // 6th Setting
1258 settings.push_back(SpdySetting(0x01000004, 0xffffffff)); 1856 settings.push_back(
1857 SpdySettingFromWireFormat(0x01000004, 0xff000001)); // 7th Setting
1858 settings.push_back(
1859 SpdySettingFromWireFormat(0x01000004, 0xffffffff)); // 8th Setting
1259 1860
1260 const unsigned char kFrameData[] = { 1861 const unsigned char kFrameData[] = {
1261 0x80, 0x02, 0x00, 0x04, 1862 0x80, kVer, 0x00, 0x04,
1262 0x00, 0x00, 0x00, 0x44, 1863 0x00, 0x00, 0x00, 0x44,
1263 0x00, 0x00, 0x00, 0x08, 1864 0x00, 0x00, 0x00, 0x08,
1865 0x00, 0x00, 0x00, 0x00, // 1st Setting
1264 0x00, 0x00, 0x00, 0x00, 1866 0x00, 0x00, 0x00, 0x00,
1265 0x00, 0x00, 0x00, 0x00, 1867 0xff, 0xff, 0xff, 0xff, // 2nd Setting
1266 0xff, 0xff, 0xff, 0xff,
1267 0x00, 0x00, 0x00, 0x01, 1868 0x00, 0x00, 0x00, 0x01,
1869 0x01, 0x00, 0x00, 0xff, // 3rd Setting
1870 0x00, 0x00, 0x00, 0x02,
1871 0x02, 0x00, 0x00, 0x01, // 4th Setting
1872 0x00, 0x00, 0x00, 0x03,
1873 0x02, 0x00, 0x00, 0x01, // 5th Setting
1874 0x00, 0x00, 0x00, 0x03,
1875 0x03, 0x00, 0x00, 0x01, // 6th Setting
1876 0x00, 0x00, 0x00, 0xff,
1877 0x04, 0x00, 0x00, 0x01, // 7th Setting
1268 0xff, 0x00, 0x00, 0x01, 1878 0xff, 0x00, 0x00, 0x01,
1269 0x00, 0x00, 0x00, 0x02, 1879 0x04, 0x00, 0x00, 0x01, // 8th Setting
1270 0x01, 0x00, 0x00, 0x02,
1271 0x00, 0x00, 0x00, 0x03,
1272 0x01, 0x00, 0x00, 0x02,
1273 0x00, 0x00, 0x00, 0x03,
1274 0x01, 0x00, 0x00, 0x03,
1275 0x00, 0x00, 0x00, 0xff,
1276 0x01, 0x00, 0x00, 0x04,
1277 0xff, 0x00, 0x00, 0x01,
1278 0x01, 0x00, 0x00, 0x04,
1279 0xff, 0xff, 0xff, 0xff, 1880 0xff, 0xff, 0xff, 0xff,
1280 }; 1881 };
1281 scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings)); 1882 scoped_ptr<SpdySettingsControlFrame> frame(framer.CreateSettings(settings));
1282 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1883 CompareFrame(kDescription,
1884 *frame,
1885 kFrameData,
1886 arraysize(kFrameData));
1283 EXPECT_EQ(SpdyFramer::kInvalidStream, 1887 EXPECT_EQ(SpdyFramer::kInvalidStream,
1284 SpdyFramer::GetControlFrameStreamId( 1888 SpdyFramer::GetControlFrameStreamId(frame.get()));
1285 reinterpret_cast<const SpdyControlFrame*>(frame.get())));
1286 } 1889 }
1287 1890
1288 { 1891 {
1289 const char kDescription[] = "Empty SETTINGS frame"; 1892 const char kDescription[] = "Empty SETTINGS frame";
1290 1893
1291 SpdySettings settings; 1894 SpdySettings settings;
1292 1895
1293 const unsigned char kFrameData[] = { 1896 const unsigned char kFrameData[] = {
1294 0x80, 0x02, 0x00, 0x04, 1897 0x80, kVer, 0x00, 0x04,
1295 0x00, 0x00, 0x00, 0x04, 1898 0x00, 0x00, 0x00, 0x04,
1296 0x00, 0x00, 0x00, 0x00, 1899 0x00, 0x00, 0x00, 0x00,
1297 }; 1900 };
1298 scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings)); 1901 scoped_ptr<SpdyFrame> frame(framer.CreateSettings(settings));
1299 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1902 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1300 } 1903 }
1301 } 1904 }
1302 1905
1303 TEST_F(SpdyFramerTest, CreateNopFrame) {
1304 SpdyFramer framer;
1305
1306 {
1307 const char kDescription[] = "NOOP frame";
1308 const unsigned char kFrameData[] = {
1309 0x80, 0x02, 0x00, 0x05,
1310 0x00, 0x00, 0x00, 0x00,
1311 };
1312 scoped_ptr<SpdyFrame> frame(framer.CreateNopFrame());
1313 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1314 EXPECT_EQ(SpdyFramer::kInvalidStream,
1315 SpdyFramer::GetControlFrameStreamId(
1316 reinterpret_cast<const SpdyControlFrame*>(frame.get())));
1317 }
1318 }
1319
1320 TEST_F(SpdyFramerTest, CreatePingFrame) { 1906 TEST_F(SpdyFramerTest, CreatePingFrame) {
1321 SpdyFramer framer; 1907 SpdyFramer framer(kVer);
1322 1908
1323 { 1909 {
1324 const char kDescription[] = "PING frame"; 1910 const char kDescription[] = "PING frame";
1325 const unsigned char kFrameData[] = { 1911 const unsigned char kFrameData[] = {
1326 0x80, 0x02, 0x00, 0x06, 1912 0x80, kVer, 0x00, 0x06,
1327 0x00, 0x00, 0x00, 0x04, 1913 0x00, 0x00, 0x00, 0x04,
1328 0x12, 0x34, 0x56, 0x78, 1914 0x12, 0x34, 0x56, 0x78,
1329 }; 1915 };
1330 scoped_ptr<SpdyFrame> frame(framer.CreatePingFrame(0x12345678u)); 1916 scoped_ptr<SpdyPingControlFrame> frame(framer.CreatePingFrame(0x12345678u));
1331 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1917 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1332 EXPECT_EQ(SpdyFramer::kInvalidStream, 1918 EXPECT_EQ(SpdyFramer::kInvalidStream,
1333 SpdyFramer::GetControlFrameStreamId( 1919 SpdyFramer::GetControlFrameStreamId(frame.get()));
1334 reinterpret_cast<const SpdyControlFrame*>(frame.get())));
1335 } 1920 }
1336 } 1921 }
1337 1922
1338 TEST_F(SpdyFramerTest, CreateGoAway) { 1923 TEST_F(SpdyFramerTest, CreateGoAway) {
1339 SpdyFramer framer; 1924 SpdyFramer framer(kVer);
1340 1925
1341 { 1926 {
1342 const char kDescription[] = "GOAWAY frame"; 1927 const char kDescription[] = "GOAWAY frame";
1343 const unsigned char kFrameData[] = { 1928 const unsigned char kFrameData[] = {
1344 0x80, 0x02, 0x00, 0x07, 1929 0x80, kVer, 0x00, 0x07,
1345 0x00, 0x00, 0x00, 0x04, 1930 0x00, 0x00, 0x00, 0x04,
1346 0x00, 0x00, 0x00, 0x00, 1931 0x00, 0x00, 0x00, 0x00,
1347 }; 1932 };
1348 scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0)); 1933 scoped_ptr<SpdyGoAwayControlFrame> frame(framer.CreateGoAway(0));
1349 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1934 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1350 EXPECT_EQ(SpdyFramer::kInvalidStream, 1935 EXPECT_EQ(SpdyFramer::kInvalidStream,
1351 SpdyFramer::GetControlFrameStreamId( 1936 SpdyFramer::GetControlFrameStreamId(frame.get()));
1352 reinterpret_cast<const SpdyControlFrame*>(frame.get())));
1353 } 1937 }
1354 1938
1355 { 1939 {
1356 const char kDescription[] = "GOAWAY frame with max stream ID"; 1940 const char kDescription[] = "GOAWAY frame with max stream ID";
1357 const unsigned char kFrameData[] = { 1941 const unsigned char kFrameData[] = {
1358 0x80, 0x02, 0x00, 0x07, 1942 0x80, kVer, 0x00, 0x07,
1359 0x00, 0x00, 0x00, 0x04, 1943 0x00, 0x00, 0x00, 0x04,
1360 0x7f, 0xff, 0xff, 0xff, 1944 0x7f, 0xff, 0xff, 0xff,
1361 }; 1945 };
1362 scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0x7FFFFFFF)); 1946 scoped_ptr<SpdyFrame> frame(framer.CreateGoAway(0x7FFFFFFF));
1363 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1947 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1364 } 1948 }
1365 } 1949 }
1366 1950
1367 TEST_F(SpdyFramerTest, CreateHeadersUncompressed) { 1951 TEST_F(SpdyFramerTest, CreateHeadersUncompressed) {
1368 SpdyFramer framer; 1952 SpdyFramer framer(kVer);
1369 framer.set_enable_compression(false); 1953 framer.set_enable_compression(false);
1370 1954
1371 { 1955 {
1372 const char kDescription[] = "HEADERS frame, no FIN"; 1956 const char kDescription[] = "HEADERS frame, no FIN";
1373 1957
1374 SpdyHeaderBlock headers; 1958 SpdyHeaderBlock headers;
1375 headers["bar"] = "foo"; 1959 headers["bar"] = "foo";
1376 headers["foo"] = "bar"; 1960 headers["foo"] = "bar";
1377 1961
1378 const unsigned char kFrameData[] = { 1962 const unsigned char kV2FrameData[] = {
1379 0x80, 0x02, 0x00, 0x08, 1963 0x80, kVer, 0x00, 0x08,
1380 0x00, 0x00, 0x00, 0x1C, 1964 0x00, 0x00, 0x00, 0x1C,
1381 0x00, 0x00, 0x00, 0x01, 1965 0x00, 0x00, 0x00, 0x01,
1382 0x00, 0x00, 0x00, 0x02, 1966 0x00, 0x00, 0x00, 0x02,
1383 0x00, 0x03, 'b', 'a', 1967 0x00, 0x03, 'b', 'a',
1384 'r', 0x00, 0x03, 'f', 1968 'r', 0x00, 0x03, 'f',
1385 'o', 'o', 0x00, 0x03, 1969 'o', 'o', 0x00, 0x03,
1386 'f', 'o', 'o', 0x00, 1970 'f', 'o', 'o', 0x00,
1387 0x03, 'b', 'a', 'r' 1971 0x03, 'b', 'a', 'r'
1388 }; 1972 };
1973 const unsigned char kV3FrameData[] = {
1974 0x80, kVer, 0x00, 0x08,
1975 0x00, 0x00, 0x00, 0x24,
1976 0x00, 0x00, 0x00, 0x01,
1977 0x00, 0x00, 0x00, 0x02,
1978 0x00, 0x00, 0x00, 0x03,
1979 'b', 'a', 'r', 0x00,
1980 0x00, 0x00, 0x03, 'f',
1981 'o', 'o', 0x00, 0x00,
1982 0x00, 0x03, 'f', 'o',
1983 'o', 0x00, 0x00, 0x00,
1984 0x03, 'b', 'a', 'r'
1985 };
1389 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders( 1986 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1390 1, CONTROL_FLAG_NONE, false, &headers)); 1987 1, CONTROL_FLAG_NONE, false, &headers));
1391 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 1988 CompareFrame(kDescription,
1989 *frame,
1990 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
1991 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
1992 : arraysize(kV3FrameData));
1392 } 1993 }
1393 1994
1394 { 1995 {
1395 const char kDescription[] = 1996 const char kDescription[] =
1396 "HEADERS frame with a 0-length header name, FIN, max stream ID"; 1997 "HEADERS frame with a 0-length header name, FIN, max stream ID";
1397 1998
1398 SpdyHeaderBlock headers; 1999 SpdyHeaderBlock headers;
1399 headers[""] = "foo"; 2000 headers[""] = "foo";
1400 headers["foo"] = "bar"; 2001 headers["foo"] = "bar";
1401 2002
1402 const unsigned char kFrameData[] = { 2003 const unsigned char kV2FrameData[] = {
1403 0x80, 0x02, 0x00, 0x08, 2004 0x80, kVer, 0x00, 0x08,
1404 0x01, 0x00, 0x00, 0x19, 2005 0x01, 0x00, 0x00, 0x19,
1405 0x7f, 0xff, 0xff, 0xff, 2006 0x7f, 0xff, 0xff, 0xff,
1406 0x00, 0x00, 0x00, 0x02, 2007 0x00, 0x00, 0x00, 0x02,
1407 0x00, 0x00, 0x00, 0x03, 2008 0x00, 0x00, 0x00, 0x03,
1408 'f', 'o', 'o', 0x00, 2009 'f', 'o', 'o', 0x00,
1409 0x03, 'f', 'o', 'o', 2010 0x03, 'f', 'o', 'o',
1410 0x00, 0x03, 'b', 'a', 2011 0x00, 0x03, 'b', 'a',
1411 'r' 2012 'r'
1412 }; 2013 };
2014 const unsigned char kV3FrameData[] = {
2015 0x80, kVer, 0x00, 0x08,
2016 0x01, 0x00, 0x00, 0x21,
2017 0x7f, 0xff, 0xff, 0xff,
2018 0x00, 0x00, 0x00, 0x02,
2019 0x00, 0x00, 0x00, 0x00,
2020 0x00, 0x00, 0x00, 0x03,
2021 'f', 'o', 'o', 0x00,
2022 0x00, 0x00, 0x03, 'f',
2023 'o', 'o', 0x00, 0x00,
2024 0x00, 0x03, 'b', 'a',
2025 'r'
2026 };
1413 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders( 2027 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1414 0x7fffffff, CONTROL_FLAG_FIN, false, &headers)); 2028 0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
1415 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 2029 CompareFrame(kDescription,
2030 *frame,
2031 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
2032 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
2033 : arraysize(kV3FrameData));
1416 } 2034 }
1417 2035
1418 { 2036 {
1419 const char kDescription[] = 2037 const char kDescription[] =
1420 "HEADERS frame with a 0-length header val, FIN, max stream ID"; 2038 "HEADERS frame with a 0-length header val, FIN, max stream ID";
1421 2039
1422 SpdyHeaderBlock headers; 2040 SpdyHeaderBlock headers;
1423 headers["bar"] = "foo"; 2041 headers["bar"] = "foo";
1424 headers["foo"] = ""; 2042 headers["foo"] = "";
1425 2043
1426 const unsigned char kFrameData[] = { 2044 const unsigned char kV2FrameData[] = {
1427 0x80, 0x02, 0x00, 0x08, 2045 0x80, kVer, 0x00, 0x08,
1428 0x01, 0x00, 0x00, 0x19, 2046 0x01, 0x00, 0x00, 0x19,
1429 0x7f, 0xff, 0xff, 0xff, 2047 0x7f, 0xff, 0xff, 0xff,
1430 0x00, 0x00, 0x00, 0x02, 2048 0x00, 0x00, 0x00, 0x02,
1431 0x00, 0x03, 'b', 'a', 2049 0x00, 0x03, 'b', 'a',
1432 'r', 0x00, 0x03, 'f', 2050 'r', 0x00, 0x03, 'f',
1433 'o', 'o', 0x00, 0x03, 2051 'o', 'o', 0x00, 0x03,
1434 'f', 'o', 'o', 0x00, 2052 'f', 'o', 'o', 0x00,
1435 0x00 2053 0x00
1436 }; 2054 };
2055 const unsigned char kV3FrameData[] = {
2056 0x80, kVer, 0x00, 0x08,
2057 0x01, 0x00, 0x00, 0x21,
2058 0x7f, 0xff, 0xff, 0xff,
2059 0x00, 0x00, 0x00, 0x02,
2060 0x00, 0x00, 0x00, 0x03,
2061 'b', 'a', 'r', 0x00,
2062 0x00, 0x00, 0x03, 'f',
2063 'o', 'o', 0x00, 0x00,
2064 0x00, 0x03, 'f', 'o',
2065 'o', 0x00, 0x00, 0x00,
2066 0x00
2067 };
1437 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders( 2068 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1438 0x7fffffff, CONTROL_FLAG_FIN, false, &headers)); 2069 0x7fffffff, CONTROL_FLAG_FIN, false, &headers));
1439 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 2070 CompareFrame(kDescription,
2071 *frame,
2072 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
2073 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
2074 : arraysize(kV3FrameData));
1440 } 2075 }
1441 } 2076 }
1442 2077
1443 TEST_F(SpdyFramerTest, CreateHeadersCompressed) { 2078 TEST_F(SpdyFramerTest, CreateHeadersCompressed) {
1444 SpdyFramer framer; 2079 SpdyFramer framer(kVer);
1445 framer.set_enable_compression(true); 2080 framer.set_enable_compression(true);
1446 2081
1447 { 2082 {
1448 const char kDescription[] = "HEADERS frame, no FIN"; 2083 const char kDescription[] = "HEADERS frame, no FIN";
1449 2084
1450 SpdyHeaderBlock headers; 2085 SpdyHeaderBlock headers;
1451 headers["bar"] = "foo"; 2086 headers["bar"] = "foo";
1452 headers["foo"] = "bar"; 2087 headers["foo"] = "bar";
1453 2088
1454 const unsigned char kFrameData[] = { 2089 const unsigned char kV2FrameData[] = {
1455 0x80, 0x02, 0x00, 0x08, 2090 0x80, kVer, 0x00, 0x08,
1456 0x00, 0x00, 0x00, 0x21, 2091 0x00, 0x00, 0x00, 0x21,
1457 0x00, 0x00, 0x00, 0x01, 2092 0x00, 0x00, 0x00, 0x01,
1458 0x00, 0x00, 0x38, 0xea, 2093 0x00, 0x00, 0x38, 0xea,
1459 0xdf, 0xa2, 0x51, 0xb2, 2094 0xdf, 0xa2, 0x51, 0xb2,
1460 0x62, 0x60, 0x62, 0x60, 2095 0x62, 0x60, 0x62, 0x60,
1461 0x4e, 0x4a, 0x2c, 0x62, 2096 0x4e, 0x4a, 0x2c, 0x62,
1462 0x60, 0x4e, 0xcb, 0xcf, 2097 0x60, 0x4e, 0xcb, 0xcf,
1463 0x87, 0x12, 0x40, 0x2e, 2098 0x87, 0x12, 0x40, 0x2e,
1464 0x00, 0x00, 0x00, 0xff, 2099 0x00, 0x00, 0x00, 0xff,
1465 0xff 2100 0xff
1466 }; 2101 };
2102 const unsigned char kV3FrameData[] = {
2103 0x80, kVer, 0x00, 0x08,
2104 0x00, 0x00, 0x00, 0x21,
2105 0x00, 0x00, 0x00, 0x01,
2106 0x38, 0xea, 0xe3, 0xc6,
2107 0xa7, 0xc2, 0x02, 0xe5,
2108 0x0e, 0x50, 0xc2, 0x4b,
2109 0x4a, 0x04, 0xe5, 0x0b,
2110 0xe6, 0xb4, 0xfc, 0x7c,
2111 0x24, 0x0a, 0x28, 0x08,
2112 0x00, 0x00, 0x00, 0xff,
2113 0xff
2114 };
1467 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders( 2115 scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1468 1, CONTROL_FLAG_NONE, true, &headers)); 2116 1, CONTROL_FLAG_NONE, true, &headers));
1469 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 2117 CompareFrame(kDescription,
2118 *frame,
2119 (SPDY_VERSION_FOR_TESTS < 3) ? kV2FrameData : kV3FrameData,
2120 (SPDY_VERSION_FOR_TESTS < 3) ? arraysize(kV2FrameData)
2121 : arraysize(kV3FrameData));
1470 } 2122 }
1471 } 2123 }
1472 2124
1473 TEST_F(SpdyFramerTest, CreateWindowUpdate) { 2125 TEST_F(SpdyFramerTest, CreateWindowUpdate) {
1474 SpdyFramer framer; 2126 SpdyFramer framer(kVer);
1475 2127
1476 { 2128 {
1477 const char kDescription[] = "WINDOW_UPDATE frame"; 2129 const char kDescription[] = "WINDOW_UPDATE frame";
1478 const unsigned char kFrameData[] = { 2130 const unsigned char kFrameData[] = {
1479 0x80, 0x02, 0x00, 0x09, 2131 0x80, kVer, 0x00, 0x09,
1480 0x00, 0x00, 0x00, 0x08, 2132 0x00, 0x00, 0x00, 0x08,
1481 0x00, 0x00, 0x00, 0x01, 2133 0x00, 0x00, 0x00, 0x01,
1482 0x00, 0x00, 0x00, 0x01, 2134 0x00, 0x00, 0x00, 0x01,
1483 }; 2135 };
1484 scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 1)); 2136 scoped_ptr<SpdyWindowUpdateControlFrame> frame(
2137 framer.CreateWindowUpdate(1, 1));
1485 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 2138 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1486 EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId( 2139 EXPECT_EQ(1u, SpdyFramer::GetControlFrameStreamId(frame.get()));
1487 reinterpret_cast<const SpdyControlFrame*>(frame.get())));
1488 } 2140 }
1489 2141
1490 { 2142 {
1491 const char kDescription[] = "WINDOW_UPDATE frame with max stream ID"; 2143 const char kDescription[] = "WINDOW_UPDATE frame with max stream ID";
1492 const unsigned char kFrameData[] = { 2144 const unsigned char kFrameData[] = {
1493 0x80, 0x02, 0x00, 0x09, 2145 0x80, kVer, 0x00, 0x09,
1494 0x00, 0x00, 0x00, 0x08, 2146 0x00, 0x00, 0x00, 0x08,
1495 0x7f, 0xff, 0xff, 0xff, 2147 0x7f, 0xff, 0xff, 0xff,
1496 0x00, 0x00, 0x00, 0x01, 2148 0x00, 0x00, 0x00, 0x01,
1497 }; 2149 };
1498 scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(0x7FFFFFFF, 1)); 2150 scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(0x7FFFFFFF, 1));
1499 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 2151 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1500 } 2152 }
1501 2153
1502 { 2154 {
1503 const char kDescription[] = "WINDOW_UPDATE frame with max window delta"; 2155 const char kDescription[] = "WINDOW_UPDATE frame with max window delta";
1504 const unsigned char kFrameData[] = { 2156 const unsigned char kFrameData[] = {
1505 0x80, 0x02, 0x00, 0x09, 2157 0x80, kVer, 0x00, 0x09,
1506 0x00, 0x00, 0x00, 0x08, 2158 0x00, 0x00, 0x00, 0x08,
1507 0x00, 0x00, 0x00, 0x01, 2159 0x00, 0x00, 0x00, 0x01,
1508 0x7f, 0xff, 0xff, 0xff, 2160 0x7f, 0xff, 0xff, 0xff,
1509 }; 2161 };
1510 scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x7FFFFFFF)); 2162 scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x7FFFFFFF));
1511 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); 2163 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1512 } 2164 }
1513 } 2165 }
1514 2166
1515 TEST_F(SpdyFramerTest, CreateCredential) {
1516 SpdyFramer framer;
1517
1518 {
1519 const char kDescription[] = "CREDENTIAL frame";
1520 const unsigned char kFrameData[] = {
1521 0x80, 0x02, 0x00, 0x0A,
1522 0x00, 0x00, 0x00, 0x33,
1523 0x00, 0x03, 0x00, 0x00,
1524 0x00, 0x05, 'p', 'r',
1525 'o', 'o', 'f', 0x00,
1526 0x00, 0x00, 0x06, 'a',
1527 ' ', 'c', 'e', 'r',
1528 't', 0x00, 0x00, 0x00,
1529 0x0C, 'a', 'n', 'o',
1530 't', 'h', 'e', 'r',
1531 ' ', 'c', 'e', 'r',
1532 't', 0x00, 0x00, 0x00,
1533 0x0A, 'f', 'i', 'n',
1534 'a', 'l', ' ', 'c',
1535 'e', 'r', 't',
1536 };
1537 SpdyCredential credential;
1538 credential.slot = 3;
1539 credential.proof = "proof";
1540 credential.certs.push_back("a cert");
1541 credential.certs.push_back("another cert");
1542 credential.certs.push_back("final cert");
1543 scoped_ptr<SpdyFrame> frame(framer.CreateCredentialFrame(credential));
1544 CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
1545 }
1546 }
1547
1548 TEST_F(SpdyFramerTest, ParseCredentialFrame) {
1549 SpdyFramer framer;
1550
1551 {
1552 unsigned char kFrameData[] = {
1553 0x80, 0x02, 0x00, 0x0A,
1554 0x00, 0x00, 0x00, 0x33,
1555 0x00, 0x03, 0x00, 0x00,
1556 0x00, 0x05, 'p', 'r',
1557 'o', 'o', 'f', 0x00,
1558 0x00, 0x00, 0x06, 'a',
1559 ' ', 'c', 'e', 'r',
1560 't', 0x00, 0x00, 0x00,
1561 0x0C, 'a', 'n', 'o',
1562 't', 'h', 'e', 'r',
1563 ' ', 'c', 'e', 'r',
1564 't', 0x00, 0x00, 0x00,
1565 0x0A, 'f', 'i', 'n',
1566 'a', 'l', ' ', 'c',
1567 'e', 'r', 't',
1568 };
1569 SpdyCredentialControlFrame frame(reinterpret_cast<char*>(kFrameData),
1570 false);
1571 SpdyCredential credential;
1572 EXPECT_TRUE(SpdyFramer::ParseCredentialData(frame.payload(),
1573 frame.length(),
1574 &credential));
1575 EXPECT_EQ(3u, credential.slot);
1576 EXPECT_EQ("proof", credential.proof);
1577 EXPECT_EQ("a cert", credential.certs.front());
1578 credential.certs.erase(credential.certs.begin());
1579 EXPECT_EQ("another cert", credential.certs.front());
1580 credential.certs.erase(credential.certs.begin());
1581 EXPECT_EQ("final cert", credential.certs.front());
1582 credential.certs.erase(credential.certs.begin());
1583 EXPECT_TRUE(credential.certs.empty());
1584 }
1585 }
1586
1587 TEST_F(SpdyFramerTest, DuplicateFrame) { 2167 TEST_F(SpdyFramerTest, DuplicateFrame) {
1588 SpdyFramer framer; 2168 SpdyFramer framer(kVer);
1589 2169
1590 { 2170 {
1591 const char kDescription[] = "PING frame"; 2171 const char kDescription[] = "PING frame";
1592 const unsigned char kFrameData[] = { 2172 const unsigned char kFrameData[] = {
1593 0x80, 0x02, 0x00, 0x06, 2173 0x80, kVer, 0x00, 0x06,
1594 0x00, 0x00, 0x00, 0x04, 2174 0x00, 0x00, 0x00, 0x04,
1595 0x12, 0x34, 0x56, 0x78, 2175 0x12, 0x34, 0x56, 0x78,
1596 }; 2176 };
1597 scoped_ptr<SpdyFrame> frame1(framer.CreatePingFrame(0x12345678u)); 2177 scoped_ptr<SpdyFrame> frame1(framer.CreatePingFrame(0x12345678u));
1598 CompareFrame(kDescription, *frame1, kFrameData, arraysize(kFrameData)); 2178 CompareFrame(kDescription, *frame1, kFrameData, arraysize(kFrameData));
1599 2179
1600 scoped_ptr<SpdyFrame> frame2(framer.DuplicateFrame(*frame1)); 2180 scoped_ptr<SpdyFrame> frame2(framer.DuplicateFrame(*frame1));
1601 CompareFrame(kDescription, *frame2, kFrameData, arraysize(kFrameData)); 2181 CompareFrame(kDescription, *frame2, kFrameData, arraysize(kFrameData));
1602 } 2182 }
1603 } 2183 }
1604 2184
1605 // This test case reproduces conditions that caused ExpandControlFrameBuffer to 2185 // This test case reproduces conditions that caused ExpandControlFrameBuffer to
1606 // fail to expand the buffer control frame buffer when it should have, allowing 2186 // fail to expand the buffer control frame buffer when it should have, allowing
1607 // the framer to overrun the buffer, and smash other heap contents. This test 2187 // the framer to overrun the buffer, and smash other heap contents. This test
1608 // relies on the debug version of the heap manager, which checks for buffer 2188 // relies on the debug version of the heap manager, which checks for buffer
1609 // overrun errors during delete processing. Regression test for b/2974814. 2189 // overrun errors during delete processing. Regression test for b/2974814.
1610 TEST_F(SpdyFramerTest, ExpandBuffer_HeapSmash) { 2190 TEST_F(SpdyFramerTest, ExpandBuffer_HeapSmash) {
1611 // Sweep through the area of problematic values, to make sure we always cover 2191 // Sweep through the area of problematic values, to make sure we always cover
1612 // the danger zone, even if it moves around at bit due to SPDY changes. 2192 // the danger zone, even if it moves around at bit due to SPDY changes.
1613 for (uint16 val2_len = SpdyFramer::kControlFrameBufferInitialSize - 50; 2193 for (uint16 val2_len = SpdyFramer::kControlFrameBufferInitialSize - 50;
1614 val2_len < SpdyFramer::kControlFrameBufferInitialSize; 2194 val2_len < SpdyFramer::kControlFrameBufferInitialSize;
1615 val2_len++) { 2195 val2_len++) {
1616 std::string val2 = std::string(val2_len, 'a'); 2196 std::string val2 = std::string(val2_len, 'a');
1617 SpdyHeaderBlock headers; 2197 SpdyHeaderBlock headers;
1618 headers["bar"] = "foo"; 2198 headers["bar"] = "foo";
1619 headers["foo"] = "baz"; 2199 headers["foo"] = "baz";
1620 headers["grue"] = val2.c_str(); 2200 headers["grue"] = val2.c_str();
1621 SpdyFramer framer; 2201 SpdyFramer framer(kVer);
1622 scoped_ptr<SpdySynStreamControlFrame> template_frame( 2202 scoped_ptr<SpdySynStreamControlFrame> template_frame(
1623 framer.CreateSynStream(1, // stream_id 2203 framer.CreateSynStream(1, // stream_id
1624 0, // associated_stream_id 2204 0, // associated_stream_id
1625 1, // priority 2205 1, // priority
1626 CONTROL_FLAG_NONE, 2206 CONTROL_FLAG_NONE,
1627 false, // compress 2207 false, // compress
1628 &headers)); 2208 &headers));
1629 EXPECT_TRUE(template_frame.get() != NULL); 2209 EXPECT_TRUE(template_frame.get() != NULL);
1630 TestSpdyVisitor visitor; 2210 TestSpdyVisitor visitor;
1631 visitor.SimulateInFramer( 2211 visitor.SimulateInFramer(
1632 reinterpret_cast<unsigned char*>(template_frame.get()->data()), 2212 reinterpret_cast<unsigned char*>(template_frame.get()->data()),
1633 template_frame.get()->length() + SpdyControlFrame::kHeaderSize); 2213 template_frame.get()->length() + SpdyControlFrame::kHeaderSize);
1634 EXPECT_EQ(1, visitor.syn_frame_count_); 2214 EXPECT_EQ(1, visitor.syn_frame_count_);
1635 } 2215 }
1636 } 2216 }
1637 2217
2218 TEST_F(SpdyFramerTest, ControlFrameSizesAreValidated) {
2219 // Create a GoAway frame that has a few extra bytes at the end.
2220 // We create enough overhead to require the framer to expand its frame buffer.
2221 size_t overhead = SpdyFramer::kUncompressedControlFrameBufferInitialSize;
2222 SpdyFramer framer(kVer);
2223 scoped_ptr<SpdyGoAwayControlFrame> goaway(framer.CreateGoAway(1));
2224 goaway->set_length(goaway->length() + overhead);
2225 std::string pad('A', overhead);
2226 TestSpdyVisitor visitor;
2227
2228 // First attempt without validation on.
2229 visitor.framer_.set_validate_control_frame_sizes(false);
2230 visitor.SimulateInFramer(
2231 reinterpret_cast<unsigned char*>(goaway->data()),
2232 goaway->length() - overhead + SpdyControlFrame::kHeaderSize);
2233 visitor.SimulateInFramer(
2234 reinterpret_cast<const unsigned char*>(pad.c_str()),
2235 overhead);
2236 EXPECT_EQ(0, visitor.error_count_); // Not an error.
2237 EXPECT_EQ(1, visitor.goaway_count_); // The goaway was parsed.
2238
2239 // Attempt with validation on.
2240 visitor.framer_.set_validate_control_frame_sizes(true);
2241 visitor.SimulateInFramer(
2242 reinterpret_cast<unsigned char*>(goaway->data()),
2243 goaway->length() - overhead + SpdyControlFrame::kHeaderSize);
2244 visitor.SimulateInFramer(
2245 reinterpret_cast<const unsigned char*>(pad.c_str()),
2246 overhead);
2247 EXPECT_EQ(1, visitor.error_count_); // This generated an error.
2248 EXPECT_EQ(1, visitor.goaway_count_); // Unchanged from before.
2249 }
2250
2251 TEST_F(SpdyFramerTest, ReadZeroLenSettingsFrame) {
2252 SpdyFramer framer(kVer);
2253 SpdySettings settings;
2254 scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
2255 control_frame->set_length(0);
2256 TestSpdyVisitor visitor;
2257 visitor.use_compression_ = false;
2258 visitor.SimulateInFramer(
2259 reinterpret_cast<unsigned char*>(control_frame->data()),
2260 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
2261 // Should generate an error, since zero-len settings frames are unsupported.
2262 EXPECT_EQ(1, visitor.error_count_);
2263 }
2264
2265 // Tests handling of SETTINGS frames with invalid length.
2266 TEST_F(SpdyFramerTest, ReadBogusLenSettingsFrame) {
2267 SpdyFramer framer(kVer);
2268 SpdySettings settings;
2269 // Add a setting to pad the frame so that we don't get a buffer overflow when
2270 // calling SimulateInFramer() below.
2271 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000002));
2272 scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
2273 control_frame->set_length(5);
2274 TestSpdyVisitor visitor;
2275 visitor.use_compression_ = false;
2276 visitor.SimulateInFramer(
2277 reinterpret_cast<unsigned char*>(control_frame->data()),
2278 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
2279 // Should generate an error, since zero-len settings frames are unsupported.
2280 EXPECT_EQ(1, visitor.error_count_);
2281 }
2282
2283 // Tests handling of SETTINGS frames larger than the frame buffer size.
2284 TEST_F(SpdyFramerTest, ReadLargeSettingsFrame) {
2285 SpdyFramer framer(kVer);
2286 SpdySettings settings;
2287 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000002));
2288 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 2), 0x00000003));
2289 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 3), 0x00000004));
2290 scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
2291 EXPECT_LT(SpdyFramer::kUncompressedControlFrameBufferInitialSize,
2292 control_frame->length() + SpdyControlFrame::kHeaderSize);
2293 TestSpdyVisitor visitor;
2294 visitor.use_compression_ = false;
2295
2296 // Read all at once.
2297 visitor.SimulateInFramer(
2298 reinterpret_cast<unsigned char*>(control_frame->data()),
2299 control_frame->length() + SpdyControlFrame::kHeaderSize);
2300 EXPECT_EQ(0, visitor.error_count_);
2301 EXPECT_EQ(settings.size(), static_cast<unsigned>(visitor.setting_count_));
2302 EXPECT_EQ(1, visitor.settings_frame_count_);
2303
2304 // Read data in small chunks.
2305 size_t framed_data = 0;
2306 size_t unframed_data = control_frame->length() +
2307 SpdyControlFrame::kHeaderSize;
2308 size_t kReadChunkSize = 5; // Read five bytes at a time.
2309 while (unframed_data > 0) {
2310 size_t to_read = std::min(kReadChunkSize, unframed_data);
2311 visitor.SimulateInFramer(
2312 reinterpret_cast<unsigned char*>(control_frame->data() + framed_data),
2313 to_read);
2314 unframed_data -= to_read;
2315 framed_data += to_read;
2316 }
2317 EXPECT_EQ(0, visitor.error_count_);
2318 EXPECT_EQ(settings.size() * 2, static_cast<unsigned>(visitor.setting_count_));
2319 EXPECT_EQ(2, visitor.settings_frame_count_);
2320 }
2321
2322 // Tests handling of SETTINGS frame with duplicate entries.
2323 TEST_F(SpdyFramerTest, ReadDuplicateSettings) {
2324 SpdyFramer framer(kVer);
2325 SpdySettings settings;
2326 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000002));
2327 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000003));
2328 // This last setting should not be processed due to error above.
2329 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 3), 0x00000003));
2330 scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
2331 TestSpdyVisitor visitor;
2332 visitor.use_compression_ = false;
2333
2334 visitor.SimulateInFramer(
2335 reinterpret_cast<unsigned char*>(control_frame->data()),
2336 control_frame->length() + SpdyControlFrame::kHeaderSize);
2337 EXPECT_EQ(1, visitor.error_count_);
2338 EXPECT_EQ(1, visitor.setting_count_);
2339 EXPECT_EQ(1, visitor.settings_frame_count_);
2340 }
2341
2342 // Tests handling of SETTINGS frame with entries out of order.
2343 TEST_F(SpdyFramerTest, ReadOutOfOrderSettings) {
2344 SpdyFramer framer(kVer);
2345 SpdySettings settings;
2346 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 2), 0x00000002));
2347 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 1), 0x00000003));
2348 // This last setting should not be processed due to error above.
2349 settings.push_back(SpdySetting(SettingsFlagsAndId(0, 3), 0x00000003));
2350 scoped_ptr<SpdyFrame> control_frame(framer.CreateSettings(settings));
2351 TestSpdyVisitor visitor;
2352 visitor.use_compression_ = false;
2353
2354 visitor.SimulateInFramer(
2355 reinterpret_cast<unsigned char*>(control_frame->data()),
2356 control_frame->length() + SpdyControlFrame::kHeaderSize);
2357 EXPECT_EQ(1, visitor.error_count_);
2358 EXPECT_EQ(1, visitor.setting_count_);
2359 EXPECT_EQ(1, visitor.settings_frame_count_);
2360 }
2361
1638 TEST_F(SpdyFramerTest, ReadCredentialFrame) { 2362 TEST_F(SpdyFramerTest, ReadCredentialFrame) {
1639 SpdyCredential credential; 2363 SpdyCredential credential;
1640 credential.slot = 3; 2364 credential.slot = 3;
1641 credential.proof = "proof"; 2365 credential.proof = "proof";
1642 credential.certs.push_back("a cert"); 2366 credential.certs.push_back("a cert");
1643 credential.certs.push_back("another cert"); 2367 credential.certs.push_back("another cert");
1644 credential.certs.push_back("final cert"); 2368 credential.certs.push_back("final cert");
1645 SpdyFramer framer; 2369 SpdyFramer framer(kVer);
1646 scoped_ptr<SpdyFrame> control_frame( 2370 scoped_ptr<SpdyFrame> control_frame(
1647 framer.CreateCredentialFrame(credential)); 2371 framer.CreateCredentialFrame(credential));
1648 EXPECT_TRUE(control_frame.get() != NULL); 2372 EXPECT_TRUE(control_frame.get() != NULL);
1649 TestSpdyVisitor visitor; 2373 TestSpdyVisitor visitor;
1650 visitor.use_compression_ = false; 2374 visitor.use_compression_ = false;
1651 visitor.SimulateInFramer( 2375 visitor.SimulateInFramer(
1652 reinterpret_cast<unsigned char*>(control_frame.get()->data()), 2376 reinterpret_cast<unsigned char*>(control_frame.get()->data()),
1653 control_frame.get()->length() + SpdyControlFrame::kHeaderSize); 2377 control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
1654 EXPECT_EQ(0, visitor.error_count_); 2378 EXPECT_EQ(0, visitor.error_count_);
1655 EXPECT_EQ(1, visitor.credential_count_); 2379 EXPECT_EQ(1, visitor.credential_count_);
1656 EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_); 2380 EXPECT_EQ(control_frame->length(), visitor.credential_buffer_length_);
1657 EXPECT_EQ(credential.slot, visitor.credential_.slot); 2381 EXPECT_EQ(credential.slot, visitor.credential_.slot);
1658 EXPECT_EQ(credential.proof, visitor.credential_.proof); 2382 EXPECT_EQ(credential.proof, visitor.credential_.proof);
1659 EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size()); 2383 EXPECT_EQ(credential.certs.size(), visitor.credential_.certs.size());
1660 for (size_t i = 0; i < credential.certs.size(); i++) { 2384 for (size_t i = 0; i < credential.certs.size(); i++) {
1661 EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]); 2385 EXPECT_EQ(credential.certs[i], visitor.credential_.certs[i]);
1662 } 2386 }
1663 } 2387 }
1664 2388
1665 TEST_F(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) { 2389 TEST_F(SpdyFramerTest, ReadCredentialFrameWithCorruptProof) {
1666 SpdyCredential credential; 2390 SpdyCredential credential;
1667 credential.slot = 3; 2391 credential.slot = 3;
1668 credential.proof = "proof"; 2392 credential.proof = "proof";
1669 credential.certs.push_back("a cert"); 2393 credential.certs.push_back("a cert");
1670 credential.certs.push_back("another cert"); 2394 credential.certs.push_back("another cert");
1671 credential.certs.push_back("final cert"); 2395 credential.certs.push_back("final cert");
1672 SpdyFramer framer; 2396 SpdyFramer framer(kVer);
1673 scoped_ptr<SpdyFrame> control_frame( 2397 scoped_ptr<SpdyFrame> control_frame(
1674 framer.CreateCredentialFrame(credential)); 2398 framer.CreateCredentialFrame(credential));
1675 EXPECT_TRUE(control_frame.get() != NULL); 2399 EXPECT_TRUE(control_frame.get() != NULL);
1676 TestSpdyVisitor visitor; 2400 TestSpdyVisitor visitor;
1677 visitor.use_compression_ = false; 2401 visitor.use_compression_ = false;
1678 unsigned char* data = 2402 unsigned char* data =
1679 reinterpret_cast<unsigned char*>(control_frame.get()->data()); 2403 reinterpret_cast<unsigned char*>(control_frame.get()->data());
1680 size_t offset = SpdyControlFrame::kHeaderSize + 4; 2404 size_t offset = SpdyControlFrame::kHeaderSize + 4;
1681 data[offset] = 0xFF; // Proof length is past the end of the frame 2405 data[offset] = 0xFF; // Proof length is past the end of the frame
1682 visitor.SimulateInFramer( 2406 visitor.SimulateInFramer(
1683 data, control_frame.get()->length() + SpdyControlFrame::kHeaderSize); 2407 data, control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
1684 EXPECT_EQ(1, visitor.error_count_); 2408 EXPECT_EQ(1, visitor.error_count_);
1685 } 2409 }
1686 2410
1687 TEST_F(SpdyFramerTest, ReadCredentialFrameWithCorruptCertificate) { 2411 TEST_F(SpdyFramerTest, ReadCredentialFrameWithCorruptCertificate) {
1688 SpdyCredential credential; 2412 SpdyCredential credential;
1689 credential.slot = 3; 2413 credential.slot = 3;
1690 credential.proof = "proof"; 2414 credential.proof = "proof";
1691 credential.certs.push_back("a cert"); 2415 credential.certs.push_back("a cert");
1692 credential.certs.push_back("another cert"); 2416 credential.certs.push_back("another cert");
1693 credential.certs.push_back("final cert"); 2417 credential.certs.push_back("final cert");
1694 SpdyFramer framer; 2418 SpdyFramer framer(kVer);
1695 scoped_ptr<SpdyFrame> control_frame( 2419 scoped_ptr<SpdyFrame> control_frame(
1696 framer.CreateCredentialFrame(credential)); 2420 framer.CreateCredentialFrame(credential));
1697 EXPECT_TRUE(control_frame.get() != NULL); 2421 EXPECT_TRUE(control_frame.get() != NULL);
1698 TestSpdyVisitor visitor; 2422 TestSpdyVisitor visitor;
1699 visitor.use_compression_ = false; 2423 visitor.use_compression_ = false;
1700 unsigned char* data = 2424 unsigned char* data =
1701 reinterpret_cast<unsigned char*>(control_frame.get()->data()); 2425 reinterpret_cast<unsigned char*>(control_frame.get()->data());
1702 size_t offset = SpdyControlFrame::kHeaderSize + credential.proof.length(); 2426 size_t offset = SpdyControlFrame::kHeaderSize + credential.proof.length();
1703 data[offset] = 0xFF; // Certificate length is past the end of the frame 2427 data[offset] = 0xFF; // Certificate length is past the end of the frame
1704 visitor.SimulateInFramer( 2428 visitor.SimulateInFramer(
1705 data, control_frame.get()->length() + SpdyControlFrame::kHeaderSize); 2429 data, control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
1706 EXPECT_EQ(1, visitor.error_count_); 2430 EXPECT_EQ(1, visitor.error_count_);
1707 } 2431 }
1708 2432
1709 TEST_F(SpdyFramerTest, ReadGarbage) { 2433 TEST_F(SpdyFramerTest, ReadGarbage) {
1710 SpdyFramer framer; 2434 SpdyFramer framer(kVer);
1711 unsigned char garbage_frame[256]; 2435 unsigned char garbage_frame[256];
1712 memset(garbage_frame, ~0, sizeof(garbage_frame)); 2436 memset(garbage_frame, ~0, sizeof(garbage_frame));
1713 TestSpdyVisitor visitor; 2437 TestSpdyVisitor visitor;
1714 visitor.use_compression_ = false; 2438 visitor.use_compression_ = false;
1715 visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame)); 2439 visitor.SimulateInFramer(garbage_frame, sizeof(garbage_frame));
1716 EXPECT_EQ(1, visitor.error_count_); 2440 EXPECT_EQ(1, visitor.error_count_);
1717 } 2441 }
1718 2442
1719 TEST_F(SpdyFramerTest, ReadGarbageWithValidVersion) { 2443 TEST_F(SpdyFramerTest, ReadGarbageWithValidVersion) {
1720 SpdyFramer framer; 2444 SpdyFramer framer(kVer);
1721 char garbage_frame[256]; 2445 char garbage_frame[256];
1722 memset(garbage_frame, ~0, sizeof(garbage_frame)); 2446 memset(garbage_frame, ~0, sizeof(garbage_frame));
1723 SpdyControlFrame control_frame(&garbage_frame[0], false); 2447 SpdyControlFrame control_frame(&garbage_frame[0], false);
1724 control_frame.set_version(kSpdyProtocolVersion); 2448 control_frame.set_version(kSpdyProtocolVersion);
1725 TestSpdyVisitor visitor; 2449 TestSpdyVisitor visitor;
1726 visitor.use_compression_ = false; 2450 visitor.use_compression_ = false;
1727 visitor.SimulateInFramer( 2451 visitor.SimulateInFramer(
1728 reinterpret_cast<unsigned char*>(control_frame.data()), 2452 reinterpret_cast<unsigned char*>(control_frame.data()),
1729 sizeof(garbage_frame)); 2453 sizeof(garbage_frame));
1730 EXPECT_EQ(1, visitor.error_count_); 2454 EXPECT_EQ(1, visitor.error_count_);
(...skipping 22 matching lines...) Expand all
1753 SpdyFramer::SPDY_FORWARD_STREAM_FRAME)); 2477 SpdyFramer::SPDY_FORWARD_STREAM_FRAME));
1754 EXPECT_STREQ("SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK", 2478 EXPECT_STREQ("SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK",
1755 SpdyFramer::StateToString( 2479 SpdyFramer::StateToString(
1756 SpdyFramer::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK)); 2480 SpdyFramer::SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK));
1757 EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK", 2481 EXPECT_STREQ("SPDY_CONTROL_FRAME_HEADER_BLOCK",
1758 SpdyFramer::StateToString( 2482 SpdyFramer::StateToString(
1759 SpdyFramer::SPDY_CONTROL_FRAME_HEADER_BLOCK)); 2483 SpdyFramer::SPDY_CONTROL_FRAME_HEADER_BLOCK));
1760 EXPECT_STREQ("SPDY_CREDENTIAL_FRAME_PAYLOAD", 2484 EXPECT_STREQ("SPDY_CREDENTIAL_FRAME_PAYLOAD",
1761 SpdyFramer::StateToString( 2485 SpdyFramer::StateToString(
1762 SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD)); 2486 SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD));
2487 EXPECT_STREQ("SPDY_SETTINGS_FRAME_PAYLOAD",
2488 SpdyFramer::StateToString(
2489 SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD));
1763 EXPECT_STREQ("UNKNOWN_STATE", 2490 EXPECT_STREQ("UNKNOWN_STATE",
1764 SpdyFramer::StateToString( 2491 SpdyFramer::StateToString(
1765 SpdyFramer::SPDY_CREDENTIAL_FRAME_PAYLOAD + 1)); 2492 SpdyFramer::SPDY_SETTINGS_FRAME_PAYLOAD + 1));
1766 } 2493 }
1767 2494
1768 TEST(SpdyFramer, ErrorCodeToStringTest) { 2495 TEST(SpdyFramer, ErrorCodeToStringTest) {
1769 EXPECT_STREQ("NO_ERROR", 2496 EXPECT_STREQ("NO_ERROR",
1770 SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_NO_ERROR)); 2497 SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_NO_ERROR));
1771 EXPECT_STREQ("INVALID_CONTROL_FRAME", 2498 EXPECT_STREQ("INVALID_CONTROL_FRAME",
1772 SpdyFramer::ErrorCodeToString( 2499 SpdyFramer::ErrorCodeToString(
1773 SpdyFramer::SPDY_INVALID_CONTROL_FRAME)); 2500 SpdyFramer::SPDY_INVALID_CONTROL_FRAME));
1774 EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE", 2501 EXPECT_STREQ("CONTROL_PAYLOAD_TOO_LARGE",
1775 SpdyFramer::ErrorCodeToString( 2502 SpdyFramer::ErrorCodeToString(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 EXPECT_STREQ("NOOP", 2550 EXPECT_STREQ("NOOP",
1824 SpdyFramer::ControlTypeToString(NOOP)); 2551 SpdyFramer::ControlTypeToString(NOOP));
1825 EXPECT_STREQ("PING", 2552 EXPECT_STREQ("PING",
1826 SpdyFramer::ControlTypeToString(PING)); 2553 SpdyFramer::ControlTypeToString(PING));
1827 EXPECT_STREQ("GOAWAY", 2554 EXPECT_STREQ("GOAWAY",
1828 SpdyFramer::ControlTypeToString(GOAWAY)); 2555 SpdyFramer::ControlTypeToString(GOAWAY));
1829 EXPECT_STREQ("HEADERS", 2556 EXPECT_STREQ("HEADERS",
1830 SpdyFramer::ControlTypeToString(HEADERS)); 2557 SpdyFramer::ControlTypeToString(HEADERS));
1831 EXPECT_STREQ("WINDOW_UPDATE", 2558 EXPECT_STREQ("WINDOW_UPDATE",
1832 SpdyFramer::ControlTypeToString(WINDOW_UPDATE)); 2559 SpdyFramer::ControlTypeToString(WINDOW_UPDATE));
1833 EXPECT_STREQ("SETTINGS", 2560 EXPECT_STREQ("CREDENTIAL",
1834 SpdyFramer::ControlTypeToString(SETTINGS)); 2561 SpdyFramer::ControlTypeToString(CREDENTIAL));
1835 EXPECT_STREQ("UNKNOWN_CONTROL_TYPE", 2562 EXPECT_STREQ("UNKNOWN_CONTROL_TYPE",
1836 SpdyFramer::ControlTypeToString(NUM_CONTROL_FRAME_TYPES)); 2563 SpdyFramer::ControlTypeToString(NUM_CONTROL_FRAME_TYPES));
1837 } 2564 }
1838 2565
1839 TEST(SpdyFramer, GetMinimumControlFrameSizeTest) { 2566 TEST(SpdyFramer, GetMinimumControlFrameSizeTest) {
1840 EXPECT_EQ(SpdySynStreamControlFrame::size(), 2567 EXPECT_EQ(SpdySynStreamControlFrame::size(),
1841 SpdyFramer::GetMinimumControlFrameSize(SYN_STREAM)); 2568 SpdyFramer::GetMinimumControlFrameSize(SYN_STREAM));
1842 EXPECT_EQ(SpdySynReplyControlFrame::size(), 2569 EXPECT_EQ(SpdySynReplyControlFrame::size(),
1843 SpdyFramer::GetMinimumControlFrameSize(SYN_REPLY)); 2570 SpdyFramer::GetMinimumControlFrameSize(SYN_REPLY));
1844 EXPECT_EQ(SpdyRstStreamControlFrame::size(), 2571 EXPECT_EQ(SpdyRstStreamControlFrame::size(),
1845 SpdyFramer::GetMinimumControlFrameSize(RST_STREAM)); 2572 SpdyFramer::GetMinimumControlFrameSize(RST_STREAM));
1846 EXPECT_EQ(SpdySettingsControlFrame::size(), 2573 EXPECT_EQ(SpdySettingsControlFrame::size(),
1847 SpdyFramer::GetMinimumControlFrameSize(SETTINGS)); 2574 SpdyFramer::GetMinimumControlFrameSize(SETTINGS));
1848 EXPECT_EQ(SpdyNoOpControlFrame::size(), 2575 EXPECT_EQ(SpdyFrame::kHeaderSize,
1849 SpdyFramer::GetMinimumControlFrameSize(NOOP)); 2576 SpdyFramer::GetMinimumControlFrameSize(NOOP));
1850 EXPECT_EQ(SpdyPingControlFrame::size(), 2577 EXPECT_EQ(SpdyPingControlFrame::size(),
1851 SpdyFramer::GetMinimumControlFrameSize(PING)); 2578 SpdyFramer::GetMinimumControlFrameSize(PING));
1852 EXPECT_EQ(SpdyGoAwayControlFrame::size(), 2579 EXPECT_EQ(SpdyGoAwayControlFrame::size(),
1853 SpdyFramer::GetMinimumControlFrameSize(GOAWAY)); 2580 SpdyFramer::GetMinimumControlFrameSize(GOAWAY));
1854 EXPECT_EQ(SpdyHeadersControlFrame::size(), 2581 EXPECT_EQ(SpdyHeadersControlFrame::size(),
1855 SpdyFramer::GetMinimumControlFrameSize(HEADERS)); 2582 SpdyFramer::GetMinimumControlFrameSize(HEADERS));
1856 EXPECT_EQ(SpdyWindowUpdateControlFrame::size(), 2583 EXPECT_EQ(SpdyWindowUpdateControlFrame::size(),
1857 SpdyFramer::GetMinimumControlFrameSize(WINDOW_UPDATE)); 2584 SpdyFramer::GetMinimumControlFrameSize(WINDOW_UPDATE));
1858 EXPECT_EQ(SpdyCredentialControlFrame::size(), 2585 EXPECT_EQ(SpdyCredentialControlFrame::size(),
1859 SpdyFramer::GetMinimumControlFrameSize(CREDENTIAL)); 2586 SpdyFramer::GetMinimumControlFrameSize(CREDENTIAL));
1860 EXPECT_EQ(static_cast<size_t>(0x7FFFFFFF), 2587 EXPECT_EQ(static_cast<size_t>(0x7FFFFFFF),
1861 SpdyFramer::GetMinimumControlFrameSize(NUM_CONTROL_FRAME_TYPES)); 2588 SpdyFramer::GetMinimumControlFrameSize(NUM_CONTROL_FRAME_TYPES));
1862 } 2589 }
1863 2590
1864 std::string RandomString(int length) { 2591 TEST(SpdyFramer, CatchProbableHttpResponse) {
1865 std::string rv; 2592 SpdyFramerTestUtil::DecompressionVisitor visitor;
1866 for (int index = 0; index < length; index++) 2593 visitor.set_allow_data_frames(true);
1867 rv += static_cast<char>('a' + (rand() % 26)); 2594 {
1868 return rv; 2595 SpdyFramer framer(kVer);
2596 framer.set_visitor(&visitor);
2597 framer.ProcessInput("HTTP/1.1", 8);
2598 EXPECT_TRUE(framer.probable_http_response());
2599 }
2600 {
2601 SpdyFramer framer(kVer);
2602 framer.set_visitor(&visitor);
2603 framer.ProcessInput("HTTP/1.0", 8);
2604 EXPECT_TRUE(framer.probable_http_response());
2605 }
2606 }
2607
2608 TEST(SpdyFramer, SettingsFlagsAndId) {
2609 const uint32 kId = 0x020304;
2610 const uint32 kFlags = 0x01;
2611 const uint32 kWireFormat =
2612 htonl((SPDY_VERSION_FOR_TESTS < 3) ? 0x04030201 : 0x01020304);
2613
2614 SettingsFlagsAndId id_and_flags =
2615 SettingsFlagsAndId::FromWireFormat(SPDY_VERSION_FOR_TESTS, kWireFormat);
2616 EXPECT_EQ(kId, id_and_flags.id());
2617 EXPECT_EQ(kFlags, id_and_flags.flags());
2618 EXPECT_EQ(kWireFormat, id_and_flags.GetWireFormat(SPDY_VERSION_FOR_TESTS));
1869 } 2619 }
1870 2620
1871 } // namespace 2621 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698