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

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

Powered by Google App Engine
This is Rietveld 408576698