| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "net/spdy/spdy_headers_block_parser.h" | 5 #include "net/spdy/spdy_headers_block_parser.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 public ::testing::TestWithParam<SpdyMajorVersion> { | 33 public ::testing::TestWithParam<SpdyMajorVersion> { |
| 34 public: | 34 public: |
| 35 ~SpdyHeadersBlockParserTest() override {} | 35 ~SpdyHeadersBlockParserTest() override {} |
| 36 | 36 |
| 37 protected: | 37 protected: |
| 38 void SetUp() override { | 38 void SetUp() override { |
| 39 // Create a parser using the mock handler. | 39 // Create a parser using the mock handler. |
| 40 spdy_version_ = GetParam(); | 40 spdy_version_ = GetParam(); |
| 41 | 41 |
| 42 parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); | 42 parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); |
| 43 length_field_size_ = | |
| 44 SpdyHeadersBlockParser::LengthFieldSizeForVersion(spdy_version_); | |
| 45 } | 43 } |
| 46 | 44 |
| 47 // Create a header block with a specified number of headers. | 45 // Create a header block with a specified number of headers. |
| 48 string CreateHeaders(uint32_t num_headers, bool insert_nulls) { | 46 string CreateHeaders(uint32_t num_headers, bool insert_nulls) { |
| 49 string headers; | 47 string headers; |
| 50 | 48 |
| 51 // First, write the number of headers in the header block. | 49 // First, write the number of headers in the header block. |
| 52 headers += EncodeLength(num_headers); | 50 headers += EncodeLength(num_headers); |
| 53 | 51 |
| 54 // Second, write the key-value pairs. | 52 // Second, write the key-value pairs. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 73 } | 71 } |
| 74 // Encode the value as SPDY header. | 72 // Encode the value as SPDY header. |
| 75 headers += EncodeLength(value.length()); | 73 headers += EncodeLength(value.length()); |
| 76 headers += value; | 74 headers += value; |
| 77 } | 75 } |
| 78 return headers; | 76 return headers; |
| 79 } | 77 } |
| 80 | 78 |
| 81 string EncodeLength(uint32_t len) { | 79 string EncodeLength(uint32_t len) { |
| 82 char buffer[4]; | 80 char buffer[4]; |
| 83 if (length_field_size_ == sizeof(uint32_t)) { | 81 uint32_t net_order_len = base::HostToNet32(len); |
| 84 uint32_t net_order_len = base::HostToNet32(len); | 82 memcpy(buffer, &net_order_len, sizeof(uint32_t)); |
| 85 memcpy(buffer, &net_order_len, length_field_size_); | 83 return string(buffer, sizeof(uint32_t)); |
| 86 } else if (length_field_size_ == sizeof(uint16_t)) { | |
| 87 uint16_t net_order_len = base::HostToNet16(static_cast<uint16_t>(len)); | |
| 88 memcpy(buffer, &net_order_len, length_field_size_); | |
| 89 } else { | |
| 90 CHECK(false) << "Invalid length field size"; | |
| 91 } | |
| 92 return string(buffer, length_field_size_); | |
| 93 } | 84 } |
| 94 | 85 |
| 95 size_t length_field_size_; | |
| 96 SpdyMajorVersion spdy_version_; | 86 SpdyMajorVersion spdy_version_; |
| 97 | 87 |
| 98 MockSpdyHeadersHandler handler_; | 88 MockSpdyHeadersHandler handler_; |
| 99 scoped_ptr<SpdyHeadersBlockParser> parser_; | 89 scoped_ptr<SpdyHeadersBlockParser> parser_; |
| 100 | 90 |
| 101 static const char *const kBaseKey; | 91 static const char *const kBaseKey; |
| 102 static const char *const kBaseValue; | 92 static const char *const kBaseValue; |
| 103 | 93 |
| 104 // Number of headers and header blocks used in the tests. | 94 // Number of headers and header blocks used in the tests. |
| 105 static const int kNumHeadersInBlock = 10; | 95 static const int kNumHeadersInBlock = 10; |
| 106 static const int kNumHeaderBlocks = 10; | 96 static const int kNumHeaderBlocks = 10; |
| 107 }; | 97 }; |
| 108 | 98 |
| 109 const char *const SpdyHeadersBlockParserTest::kBaseKey = "test_key"; | 99 const char *const SpdyHeadersBlockParserTest::kBaseKey = "test_key"; |
| 110 const char *const SpdyHeadersBlockParserTest::kBaseValue = "test_value"; | 100 const char *const SpdyHeadersBlockParserTest::kBaseValue = "test_value"; |
| 111 | 101 |
| 112 // All tests are run with 3 different SPDY versions: SPDY/2, SPDY/3, HTTP/2. | 102 // All tests are run with SPDY/3 and HTTP/2. |
| 113 INSTANTIATE_TEST_CASE_P(SpdyHeadersBlockParserTests, | 103 INSTANTIATE_TEST_CASE_P(SpdyHeadersBlockParserTests, |
| 114 SpdyHeadersBlockParserTest, | 104 SpdyHeadersBlockParserTest, |
| 115 ::testing::Values(SPDY2, SPDY3, HTTP2)); | 105 ::testing::Values(SPDY3, HTTP2)); |
| 116 | 106 |
| 117 TEST_P(SpdyHeadersBlockParserTest, BasicTest) { | 107 TEST_P(SpdyHeadersBlockParserTest, BasicTest) { |
| 118 // Sanity test, verify that we parse out correctly a block with | 108 // Sanity test, verify that we parse out correctly a block with |
| 119 // a single key-value pair and that we notify when we start and finish | 109 // a single key-value pair and that we notify when we start and finish |
| 120 // handling a headers block. | 110 // handling a headers block. |
| 121 EXPECT_EQ(spdy_version_, parser_->spdy_version()); | 111 EXPECT_EQ(spdy_version_, parser_->spdy_version()); |
| 122 | 112 |
| 123 EXPECT_CALL(handler_, OnHeaderBlockStart()).Times(1); | 113 EXPECT_CALL(handler_, OnHeaderBlockStart()).Times(1); |
| 124 string expect_key = kBaseKey + IntToString(0); | 114 string expect_key = kBaseKey + IntToString(0); |
| 125 string expect_value = kBaseValue + IntToString(0); | 115 string expect_value = kBaseValue + IntToString(0); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); | 201 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); |
| 212 EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); | 202 EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); |
| 213 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, NULL, 0)); | 203 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, NULL, 0)); |
| 214 } | 204 } |
| 215 } | 205 } |
| 216 } | 206 } |
| 217 | 207 |
| 218 TEST_P(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) { | 208 TEST_P(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) { |
| 219 // Header block with too many headers. | 209 // Header block with too many headers. |
| 220 { | 210 { |
| 221 string headers = EncodeLength( | 211 string headers = EncodeLength(parser_->MaxNumberOfHeaders() + 1); |
| 222 parser_->MaxNumberOfHeadersForVersion(spdy_version_) + 1); | |
| 223 EXPECT_FALSE(parser_-> | 212 EXPECT_FALSE(parser_-> |
| 224 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); | 213 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); |
| 225 EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE, | 214 EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE, |
| 226 parser_->get_error()); | 215 parser_->get_error()); |
| 227 } | 216 } |
| 228 parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); | 217 parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); |
| 229 // Header block with one header, which has a too-long key. | 218 // Header block with one header, which has a too-long key. |
| 230 { | 219 { |
| 231 string headers = EncodeLength(1) + EncodeLength( | 220 string headers = EncodeLength(1) + EncodeLength( |
| 232 SpdyHeadersBlockParser::kMaximumFieldLength + 1); | 221 SpdyHeadersBlockParser::kMaximumFieldLength + 1); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 string headers(CreateHeaders(kNumHeadersInBlock, false)); | 258 string headers(CreateHeaders(kNumHeadersInBlock, false)); |
| 270 bool result; | 259 bool result; |
| 271 EXPECT_DFATAL( | 260 EXPECT_DFATAL( |
| 272 result = parser_->HandleControlFrameHeadersData(0, headers.data(), 1), | 261 result = parser_->HandleControlFrameHeadersData(0, headers.data(), 1), |
| 273 "Expected nonzero stream id, saw: 0"); | 262 "Expected nonzero stream id, saw: 0"); |
| 274 EXPECT_FALSE(result); | 263 EXPECT_FALSE(result); |
| 275 EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_->get_error()); | 264 EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_->get_error()); |
| 276 } | 265 } |
| 277 | 266 |
| 278 } // namespace net | 267 } // namespace net |
| OLD | NEW |