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" |
11 #include "base/sys_byteorder.h" | 11 #include "base/sys_byteorder.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 12 #include "testing/gmock/include/gmock/gmock.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 | 14 |
15 namespace net { | 15 namespace net { |
16 | 16 |
17 using base::IntToString; | 17 using base::IntToString; |
18 using base::StringPiece; | 18 using base::StringPiece; |
19 using std::string; | 19 using std::string; |
20 using testing::ElementsAre; | 20 using testing::ElementsAre; |
21 using testing::ElementsAreArray; | 21 using testing::ElementsAreArray; |
22 | 22 |
23 // A mock the handler class to check that we parse out the correct headers | 23 // A mock the handler class to check that we parse out the correct headers |
24 // and call the callback methods when we should. | 24 // and call the callback methods when we should. |
25 class MockSpdyHeadersHandler : public SpdyHeadersHandlerInterface { | 25 class MockSpdyHeadersHandler : public SpdyHeadersHandlerInterface { |
26 public: | 26 public: |
27 MOCK_METHOD2(OnHeaderBlock, void(SpdyStreamId stream_id, | 27 MOCK_METHOD2(OnHeaderBlock, |
28 uint32_t num_of_headers)); | 28 void(SpdyStreamId stream_id, uint32_t num_of_headers)); |
29 MOCK_METHOD1(OnHeaderBlockEnd, void(SpdyStreamId stream_id)); | 29 MOCK_METHOD1(OnHeaderBlockEnd, void(SpdyStreamId stream_id)); |
30 MOCK_METHOD3(OnHeader, void(SpdyStreamId stream_id, | 30 MOCK_METHOD3(OnHeader, |
31 StringPiece, | 31 void(SpdyStreamId stream_id, StringPiece, StringPiece)); |
32 StringPiece)); | |
33 }; | 32 }; |
34 | 33 |
35 class SpdyHeadersBlockParserTest : | 34 class SpdyHeadersBlockParserTest |
36 public ::testing::TestWithParam<SpdyMajorVersion> { | 35 : public ::testing::TestWithParam<SpdyMajorVersion> { |
37 public: | 36 public: |
38 virtual ~SpdyHeadersBlockParserTest() {} | 37 virtual ~SpdyHeadersBlockParserTest() {} |
39 | 38 |
40 protected: | 39 protected: |
41 virtual void SetUp() { | 40 virtual void SetUp() { |
42 // Create a parser using the mock handler. | 41 // Create a parser using the mock handler. |
43 spdy_version_ = GetParam(); | 42 spdy_version_ = GetParam(); |
44 parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); | 43 parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); |
45 length_field_size_ = | 44 length_field_size_ = |
46 SpdyHeadersBlockParser::LengthFieldSizeForVersion(spdy_version_); | 45 SpdyHeadersBlockParser::LengthFieldSizeForVersion(spdy_version_); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 ::testing::Values(SPDY2, SPDY3, SPDY4)); | 116 ::testing::Values(SPDY2, SPDY3, SPDY4)); |
118 | 117 |
119 TEST_P(SpdyHeadersBlockParserTest, BasicTest) { | 118 TEST_P(SpdyHeadersBlockParserTest, BasicTest) { |
120 // Sanity test, verify that we parse out correctly a block with | 119 // Sanity test, verify that we parse out correctly a block with |
121 // a single key-value pair and that we notify when we start and finish | 120 // a single key-value pair and that we notify when we start and finish |
122 // handling a headers block. | 121 // handling a headers block. |
123 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); | 122 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); |
124 | 123 |
125 std::string expect_key = base_key + IntToString(0); | 124 std::string expect_key = base_key + IntToString(0); |
126 std::string expect_value = base_value + IntToString(0); | 125 std::string expect_value = base_value + IntToString(0); |
127 EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), | 126 EXPECT_CALL(handler_, |
128 StringPiece(expect_value))).Times(1); | 127 OnHeader(1, StringPiece(expect_key), StringPiece(expect_value))) |
| 128 .Times(1); |
129 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); | 129 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); |
130 | 130 |
131 string headers(CreateHeaders(1, false)); | 131 string headers(CreateHeaders(1, false)); |
132 EXPECT_TRUE(parser_-> | 132 EXPECT_TRUE(parser_->HandleControlFrameHeadersData( |
133 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); | 133 1, headers.c_str(), headers.length())); |
134 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); | 134 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); |
135 } | 135 } |
136 | 136 |
137 TEST_P(SpdyHeadersBlockParserTest, NullsSupportedTest) { | 137 TEST_P(SpdyHeadersBlockParserTest, NullsSupportedTest) { |
138 // Sanity test, verify that we parse out correctly a block with | 138 // Sanity test, verify that we parse out correctly a block with |
139 // a single key-value pair when the key and value contain null charecters. | 139 // a single key-value pair when the key and value contain null charecters. |
140 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); | 140 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); |
141 | 141 |
142 std::string expect_key = base_key + string("\0", 1) + IntToString(0); | 142 std::string expect_key = base_key + string("\0", 1) + IntToString(0); |
143 std::string expect_value = base_value + string("\0", 1) + IntToString(0); | 143 std::string expect_value = base_value + string("\0", 1) + IntToString(0); |
144 EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), | 144 EXPECT_CALL(handler_, |
145 StringPiece(expect_value))).Times(1); | 145 OnHeader(1, StringPiece(expect_key), StringPiece(expect_value))) |
| 146 .Times(1); |
146 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); | 147 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); |
147 | 148 |
148 string headers(CreateHeaders(1, true)); | 149 string headers(CreateHeaders(1, true)); |
149 EXPECT_TRUE(parser_-> | 150 EXPECT_TRUE(parser_->HandleControlFrameHeadersData( |
150 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); | 151 1, headers.c_str(), headers.length())); |
151 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); | 152 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); |
152 } | 153 } |
153 | 154 |
154 TEST_P(SpdyHeadersBlockParserTest, MultipleBlocksAndHeadersWithPartialData) { | 155 TEST_P(SpdyHeadersBlockParserTest, MultipleBlocksAndHeadersWithPartialData) { |
155 testing::InSequence s; | 156 testing::InSequence s; |
156 | 157 |
157 // The mock doesn't retain storage of arguments, so keep them in scope. | 158 // The mock doesn't retain storage of arguments, so keep them in scope. |
158 std::vector<string> retained_arguments; | 159 std::vector<string> retained_arguments; |
159 for (int i = 0; i < kNumHeadersInBlock; i++) { | 160 for (int i = 0; i < kNumHeadersInBlock; i++) { |
160 retained_arguments.push_back(base_key + IntToString(i)); | 161 retained_arguments.push_back(base_key + IntToString(i)); |
161 retained_arguments.push_back(base_value + IntToString(i)); | 162 retained_arguments.push_back(base_value + IntToString(i)); |
162 } | 163 } |
163 // For each block we expect to parse out the headers in order. | 164 // For each block we expect to parse out the headers in order. |
164 for (int i = 0; i < kNumHeaderBlocks; i++) { | 165 for (int i = 0; i < kNumHeaderBlocks; i++) { |
165 EXPECT_CALL(handler_, OnHeaderBlock(i, kNumHeadersInBlock)).Times(1); | 166 EXPECT_CALL(handler_, OnHeaderBlock(i, kNumHeadersInBlock)).Times(1); |
166 for (int j = 0; j < kNumHeadersInBlock; j++) { | 167 for (int j = 0; j < kNumHeadersInBlock; j++) { |
167 EXPECT_CALL(handler_, OnHeader( | 168 EXPECT_CALL(handler_, |
168 i, | 169 OnHeader(i, |
169 StringPiece(retained_arguments[2 * j]), | 170 StringPiece(retained_arguments[2 * j]), |
170 StringPiece(retained_arguments[2 * j + 1]))).Times(1); | 171 StringPiece(retained_arguments[2 * j + 1]))) |
| 172 .Times(1); |
171 } | 173 } |
172 EXPECT_CALL(handler_, OnHeaderBlockEnd(i)).Times(1); | 174 EXPECT_CALL(handler_, OnHeaderBlockEnd(i)).Times(1); |
173 } | 175 } |
174 // Parse the header blocks, feeding the parser one byte at a time. | 176 // Parse the header blocks, feeding the parser one byte at a time. |
175 for (int i = 0; i < kNumHeaderBlocks; i++) { | 177 for (int i = 0; i < kNumHeaderBlocks; i++) { |
176 string headers(CreateHeaders(kNumHeadersInBlock, false)); | 178 string headers(CreateHeaders(kNumHeadersInBlock, false)); |
177 for (string::iterator it = headers.begin(); it != headers.end(); ++it) { | 179 for (string::iterator it = headers.begin(); it != headers.end(); ++it) { |
178 if ((it + 1) == headers.end()) { | 180 if ((it + 1) == headers.end()) { |
179 // Last byte completes the block. | 181 // Last byte completes the block. |
180 EXPECT_TRUE(parser_->HandleControlFrameHeadersData(i, &(*it), 1)); | 182 EXPECT_TRUE(parser_->HandleControlFrameHeadersData(i, &(*it), 1)); |
181 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); | 183 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); |
182 } else { | 184 } else { |
183 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(i, &(*it), 1)); | 185 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(i, &(*it), 1)); |
184 EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); | 186 EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); |
185 } | 187 } |
186 } | 188 } |
187 } | 189 } |
188 } | 190 } |
189 | 191 |
190 TEST_P(SpdyHeadersBlockParserTest, HandlesEmptyCallsTest) { | 192 TEST_P(SpdyHeadersBlockParserTest, HandlesEmptyCallsTest) { |
191 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); | 193 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); |
192 | 194 |
193 string expect_key = base_key + IntToString(0); | 195 string expect_key = base_key + IntToString(0); |
194 string expect_value = base_value + IntToString(0); | 196 string expect_value = base_value + IntToString(0); |
195 EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), | 197 EXPECT_CALL(handler_, |
196 StringPiece(expect_value))).Times(1); | 198 OnHeader(1, StringPiece(expect_key), StringPiece(expect_value))) |
| 199 .Times(1); |
197 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); | 200 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); |
198 | 201 |
199 // Send a header in pieces with intermediate empty calls. | 202 // Send a header in pieces with intermediate empty calls. |
200 string headers(CreateHeaders(1, false)); | 203 string headers(CreateHeaders(1, false)); |
201 for (string::iterator it = headers.begin(); it != headers.end(); ++it) { | 204 for (string::iterator it = headers.begin(); it != headers.end(); ++it) { |
202 if ((it + 1) == headers.end()) { | 205 if ((it + 1) == headers.end()) { |
203 // Last byte completes the block. | 206 // Last byte completes the block. |
204 EXPECT_TRUE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); | 207 EXPECT_TRUE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); |
205 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); | 208 EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); |
206 } else { | 209 } else { |
207 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); | 210 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); |
208 EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); | 211 EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); |
209 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, NULL, 0)); | 212 EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, NULL, 0)); |
210 } | 213 } |
211 } | 214 } |
212 } | 215 } |
213 | 216 |
214 TEST_P(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) { | 217 TEST_P(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) { |
215 // Header block with too many headers. | 218 // Header block with too many headers. |
216 { | 219 { |
217 string headers = EncodeLength( | 220 string headers = |
218 parser_->MaxNumberOfHeadersForVersion(spdy_version_) + 1); | 221 EncodeLength(parser_->MaxNumberOfHeadersForVersion(spdy_version_) + 1); |
219 EXPECT_FALSE(parser_-> | 222 EXPECT_FALSE(parser_->HandleControlFrameHeadersData( |
220 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); | 223 1, headers.c_str(), headers.length())); |
221 EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE, | 224 EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE, |
222 parser_->get_error()); | 225 parser_->get_error()); |
223 } | 226 } |
224 parser_->Reset(); | 227 parser_->Reset(); |
225 // Header block with one header, which has a too-long key. | 228 // Header block with one header, which has a too-long key. |
226 { | 229 { |
227 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); | 230 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); |
228 | 231 |
229 string headers = EncodeLength(1) + EncodeLength( | 232 string headers = |
230 SpdyHeadersBlockParser::kMaximumFieldLength + 1); | 233 EncodeLength(1) + |
231 EXPECT_FALSE(parser_-> | 234 EncodeLength(SpdyHeadersBlockParser::kMaximumFieldLength + 1); |
232 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); | 235 EXPECT_FALSE(parser_->HandleControlFrameHeadersData( |
| 236 1, headers.c_str(), headers.length())); |
233 EXPECT_EQ(SpdyHeadersBlockParser::HEADER_FIELD_TOO_LARGE, | 237 EXPECT_EQ(SpdyHeadersBlockParser::HEADER_FIELD_TOO_LARGE, |
234 parser_->get_error()); | 238 parser_->get_error()); |
235 } | 239 } |
236 } | 240 } |
237 | 241 |
238 TEST_P(SpdyHeadersBlockParserTest, ExtraDataTest) { | 242 TEST_P(SpdyHeadersBlockParserTest, ExtraDataTest) { |
239 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); | 243 EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); |
240 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); | 244 EXPECT_CALL(handler_, OnHeaderBlockEnd(1)).Times(1); |
241 | 245 |
242 string expect_key = base_key + IntToString(0); | 246 string expect_key = base_key + IntToString(0); |
243 string expect_value = base_value + IntToString(0); | 247 string expect_value = base_value + IntToString(0); |
244 EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), | 248 EXPECT_CALL(handler_, |
245 StringPiece(expect_value))).Times(1); | 249 OnHeader(1, StringPiece(expect_key), StringPiece(expect_value))) |
| 250 .Times(1); |
246 | 251 |
247 string headers = CreateHeaders(1, false) + "foobar"; | 252 string headers = CreateHeaders(1, false) + "foobar"; |
248 EXPECT_FALSE(parser_-> | 253 EXPECT_FALSE(parser_->HandleControlFrameHeadersData( |
249 HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); | 254 1, headers.c_str(), headers.length())); |
250 EXPECT_EQ(SpdyHeadersBlockParser::TOO_MUCH_DATA, parser_->get_error()); | 255 EXPECT_EQ(SpdyHeadersBlockParser::TOO_MUCH_DATA, parser_->get_error()); |
251 } | 256 } |
252 | 257 |
253 } // namespace net | 258 } // namespace net |
OLD | NEW |