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