OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <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 = 2; |
| 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; |
| 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_spdy2 { |
| 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 Loading... |
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 Loading... |
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 Loading... |
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_spdy2 |
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_spdy2::CompareCharArraysWithHexError; |
319 using spdy::test::TestSpdyVisitor; | 471 using spdy::test_spdy2::SpdyFramerTestUtil; |
| 472 using spdy::test_spdy2::TestSpdyVisitor; |
320 | 473 |
321 namespace spdy { | 474 namespace spdy { |
322 | 475 |
323 TEST(SpdyFrameBuilderTest, WriteLimits) { | 476 TEST(SpdyFrameBuilderSpdy2Test, 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 SpdyFramerSpdy2Test : 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 Loading... |
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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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 Loading... |
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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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(SpdyFramerSpdy2Test, 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 |
OLD | NEW |