| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/http2/hpack/decoder/hpack_block_decoder.h" | 5 #include "net/http2/hpack/decoder/hpack_block_decoder.h" |
| 6 | 6 |
| 7 // Tests of HpackBlockDecoder. | 7 // Tests of HpackBlockDecoder. |
| 8 | 8 |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| 11 #include "base/bind.h" | |
| 12 #include "base/bind_helpers.h" | |
| 13 #include "net/http2/decoder/decode_buffer.h" | 11 #include "net/http2/decoder/decode_buffer.h" |
| 14 #include "net/http2/hpack/decoder/hpack_block_collector.h" | 12 #include "net/http2/hpack/decoder/hpack_block_collector.h" |
| 15 #include "net/http2/hpack/http2_hpack_constants.h" | 13 #include "net/http2/hpack/http2_hpack_constants.h" |
| 16 #include "net/http2/hpack/tools/hpack_block_builder.h" | 14 #include "net/http2/hpack/tools/hpack_block_builder.h" |
| 17 #include "net/http2/hpack/tools/hpack_example.h" | 15 #include "net/http2/hpack/tools/hpack_example.h" |
| 18 #include "net/http2/tools/failure.h" | 16 #include "net/http2/tools/failure.h" |
| 19 #include "net/http2/tools/http2_random.h" | 17 #include "net/http2/tools/http2_random.h" |
| 20 #include "net/http2/tools/random_decoder_test.h" | 18 #include "net/http2/tools/random_decoder_test.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 20 |
| 23 using ::testing::AssertionSuccess; | 21 using ::testing::AssertionSuccess; |
| 24 using std::string; | 22 using std::string; |
| 25 using base::StringPiece; | 23 using base::StringPiece; |
| 26 | 24 |
| 27 namespace net { | 25 namespace net { |
| 28 namespace test { | 26 namespace test { |
| 29 namespace { | 27 namespace { |
| 30 | 28 |
| 31 class HpackBlockDecoderTest : public RandomDecoderTest { | 29 class HpackBlockDecoderTest : public RandomDecoderTest { |
| 32 public: | |
| 33 AssertionResult VerifyExpected(const HpackBlockCollector& expected) { | |
| 34 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); | |
| 35 } | |
| 36 | |
| 37 AssertionResult ValidateForSpecExample_C_2_1() { | |
| 38 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( | |
| 39 HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false, | |
| 40 "custom-header")); | |
| 41 } | |
| 42 | |
| 43 AssertionResult ValidateForSpecExample_C_2_2() { | |
| 44 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralValueHeader( | |
| 45 HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path")); | |
| 46 } | |
| 47 | |
| 48 AssertionResult ValidateForSpecExample_C_2_3() { | |
| 49 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( | |
| 50 HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false, | |
| 51 "secret")); | |
| 52 } | |
| 53 | |
| 54 AssertionResult ValidateForSpecExample_C_2_4() { | |
| 55 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleIndexedHeader(2)); | |
| 56 } | |
| 57 | 30 |
| 58 protected: | 31 protected: |
| 59 HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) { | 32 HpackBlockDecoderTest() : listener_(&collector_), decoder_(&listener_) { |
| 60 stop_decode_on_done_ = false; | 33 stop_decode_on_done_ = false; |
| 61 decoder_.Reset(); | 34 decoder_.Reset(); |
| 62 // Make sure logging doesn't crash. Not examining the result. | 35 // Make sure logging doesn't crash. Not examining the result. |
| 63 std::ostringstream strm; | 36 std::ostringstream strm; |
| 64 strm << decoder_; | 37 strm << decoder_; |
| 65 } | 38 } |
| 66 | 39 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 78 |
| 106 string Rand8String() { return Random().RandString(Rand8()); } | 79 string Rand8String() { return Random().RandString(Rand8()); } |
| 107 | 80 |
| 108 HpackBlockCollector collector_; | 81 HpackBlockCollector collector_; |
| 109 HpackEntryDecoderVLoggingListener listener_; | 82 HpackEntryDecoderVLoggingListener listener_; |
| 110 HpackBlockDecoder decoder_; | 83 HpackBlockDecoder decoder_; |
| 111 }; | 84 }; |
| 112 | 85 |
| 113 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1 | 86 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.1 |
| 114 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) { | 87 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_1) { |
| 115 NoArgValidator do_check = | 88 NoArgValidator do_check = [this]() { |
| 116 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_1, | 89 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( |
| 117 base::Unretained(this)); | 90 HpackEntryType::kIndexedLiteralHeader, false, "custom-key", false, |
| 91 "custom-header")); |
| 92 }; |
| 118 EXPECT_TRUE( | 93 EXPECT_TRUE( |
| 119 DecodeHpackExampleAndValidateSeveralWays(R"( | 94 DecodeHpackExampleAndValidateSeveralWays(R"( |
| 120 40 | == Literal indexed == | 95 40 | == Literal indexed == |
| 121 0a | Literal name (len = 10) | 96 0a | Literal name (len = 10) |
| 122 6375 7374 6f6d 2d6b 6579 | custom-key | 97 6375 7374 6f6d 2d6b 6579 | custom-key |
| 123 0d | Literal value (len = 13) | 98 0d | Literal value (len = 13) |
| 124 6375 7374 6f6d 2d68 6561 6465 72 | custom-header | 99 6375 7374 6f6d 2d68 6561 6465 72 | custom-header |
| 125 | -> custom-key: | 100 | -> custom-key: |
| 126 | custom-header | 101 | custom-header |
| 127 )", | 102 )", |
| 128 ValidateDoneAndEmpty(do_check))); | 103 ValidateDoneAndEmpty(do_check))); |
| 129 EXPECT_TRUE(do_check.Run()); | 104 EXPECT_TRUE(do_check()); |
| 130 } | 105 } |
| 131 | 106 |
| 132 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2 | 107 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.2 |
| 133 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) { | 108 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_2) { |
| 134 NoArgValidator do_check = | 109 NoArgValidator do_check = [this]() { |
| 135 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_2, | 110 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralValueHeader( |
| 136 base::Unretained(this)); | 111 HpackEntryType::kUnindexedLiteralHeader, 4, false, "/sample/path")); |
| 112 }; |
| 137 EXPECT_TRUE( | 113 EXPECT_TRUE( |
| 138 DecodeHpackExampleAndValidateSeveralWays(R"( | 114 DecodeHpackExampleAndValidateSeveralWays(R"( |
| 139 04 | == Literal not indexed == | 115 04 | == Literal not indexed == |
| 140 | Indexed name (idx = 4) | 116 | Indexed name (idx = 4) |
| 141 | :path | 117 | :path |
| 142 0c | Literal value (len = 12) | 118 0c | Literal value (len = 12) |
| 143 2f73 616d 706c 652f 7061 7468 | /sample/path | 119 2f73 616d 706c 652f 7061 7468 | /sample/path |
| 144 | -> :path: /sample/path | 120 | -> :path: /sample/path |
| 145 )", | 121 )", |
| 146 ValidateDoneAndEmpty(do_check))); | 122 ValidateDoneAndEmpty(do_check))); |
| 147 EXPECT_TRUE(do_check.Run()); | 123 EXPECT_TRUE(do_check()); |
| 148 } | 124 } |
| 149 | 125 |
| 150 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3 | 126 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.3 |
| 151 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) { | 127 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_3) { |
| 152 NoArgValidator do_check = | 128 NoArgValidator do_check = [this]() { |
| 153 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_3, | 129 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleLiteralNameValueHeader( |
| 154 base::Unretained(this)); | 130 HpackEntryType::kNeverIndexedLiteralHeader, false, "password", false, |
| 131 "secret")); |
| 132 }; |
| 155 EXPECT_TRUE( | 133 EXPECT_TRUE( |
| 156 DecodeHpackExampleAndValidateSeveralWays(R"( | 134 DecodeHpackExampleAndValidateSeveralWays(R"( |
| 157 10 | == Literal never indexed == | 135 10 | == Literal never indexed == |
| 158 08 | Literal name (len = 8) | 136 08 | Literal name (len = 8) |
| 159 7061 7373 776f 7264 | password | 137 7061 7373 776f 7264 | password |
| 160 06 | Literal value (len = 6) | 138 06 | Literal value (len = 6) |
| 161 7365 6372 6574 | secret | 139 7365 6372 6574 | secret |
| 162 | -> password: secret | 140 | -> password: secret |
| 163 )", | 141 )", |
| 164 ValidateDoneAndEmpty(do_check))); | 142 ValidateDoneAndEmpty(do_check))); |
| 165 EXPECT_TRUE(do_check.Run()); | 143 EXPECT_TRUE(do_check()); |
| 166 } | 144 } |
| 167 | 145 |
| 168 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4 | 146 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.2.4 |
| 169 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) { | 147 TEST_F(HpackBlockDecoderTest, SpecExample_C_2_4) { |
| 170 NoArgValidator do_check = | 148 NoArgValidator do_check = [this]() { |
| 171 base::Bind(&HpackBlockDecoderTest::ValidateForSpecExample_C_2_4, | 149 VERIFY_AND_RETURN_SUCCESS(collector_.ValidateSoleIndexedHeader(2)); |
| 172 base::Unretained(this)); | 150 }; |
| 173 EXPECT_TRUE( | 151 EXPECT_TRUE( |
| 174 DecodeHpackExampleAndValidateSeveralWays(R"( | 152 DecodeHpackExampleAndValidateSeveralWays(R"( |
| 175 82 | == Indexed - Add == | 153 82 | == Indexed - Add == |
| 176 | idx = 2 | 154 | idx = 2 |
| 177 | -> :method: GET | 155 | -> :method: GET |
| 178 )", | 156 )", |
| 179 ValidateDoneAndEmpty(do_check))); | 157 ValidateDoneAndEmpty(do_check))); |
| 180 EXPECT_TRUE(do_check.Run()); | 158 EXPECT_TRUE(do_check()); |
| 181 } | 159 } |
| 182 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 | 160 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.3.1 |
| 183 TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) { | 161 TEST_F(HpackBlockDecoderTest, SpecExample_C_3_1) { |
| 184 string example = R"( | 162 string example = R"( |
| 185 82 | == Indexed - Add == | 163 82 | == Indexed - Add == |
| 186 | idx = 2 | 164 | idx = 2 |
| 187 | -> :method: GET | 165 | -> :method: GET |
| 188 86 | == Indexed - Add == | 166 86 | == Indexed - Add == |
| 189 | idx = 6 | 167 | idx = 6 |
| 190 | -> :scheme: http | 168 | -> :scheme: http |
| 191 84 | == Indexed - Add == | 169 84 | == Indexed - Add == |
| 192 | idx = 4 | 170 | idx = 4 |
| 193 | -> :path: / | 171 | -> :path: / |
| 194 41 | == Literal indexed == | 172 41 | == Literal indexed == |
| 195 | Indexed name (idx = 1) | 173 | Indexed name (idx = 1) |
| 196 | :authority | 174 | :authority |
| 197 0f | Literal value (len = 15) | 175 0f | Literal value (len = 15) |
| 198 7777 772e 6578 616d 706c 652e 636f 6d | www.example.com | 176 7777 772e 6578 616d 706c 652e 636f 6d | www.example.com |
| 199 | -> :authority: | 177 | -> :authority: |
| 200 | www.example.com | 178 | www.example.com |
| 201 )"; | 179 )"; |
| 202 HpackBlockCollector expected; | 180 HpackBlockCollector expected; |
| 203 expected.ExpectIndexedHeader(2); | 181 expected.ExpectIndexedHeader(2); |
| 204 expected.ExpectIndexedHeader(6); | 182 expected.ExpectIndexedHeader(6); |
| 205 expected.ExpectIndexedHeader(4); | 183 expected.ExpectIndexedHeader(4); |
| 206 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 184 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
| 207 1, false, "www.example.com"); | 185 1, false, "www.example.com"); |
| 208 NoArgValidator do_check = base::Bind(&HpackBlockDecoderTest::VerifyExpected, | 186 NoArgValidator do_check = [expected, this]() { |
| 209 base::Unretained(this), expected); | 187 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); |
| 188 }; |
| 210 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( | 189 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( |
| 211 example, ValidateDoneAndEmpty(do_check))); | 190 example, ValidateDoneAndEmpty(do_check))); |
| 212 EXPECT_TRUE(do_check.Run()); | 191 EXPECT_TRUE(do_check()); |
| 213 } | 192 } |
| 214 | 193 |
| 215 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1 | 194 // http://httpwg.org/specs/rfc7541.html#rfc.section.C.5.1 |
| 216 TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) { | 195 TEST_F(HpackBlockDecoderTest, SpecExample_C_5_1) { |
| 217 string example = R"( | 196 string example = R"( |
| 218 48 | == Literal indexed == | 197 48 | == Literal indexed == |
| 219 | Indexed name (idx = 8) | 198 | Indexed name (idx = 8) |
| 220 | :status | 199 | :status |
| 221 03 | Literal value (len = 3) | 200 03 | Literal value (len = 3) |
| 222 3330 32 | 302 | 201 3330 32 | 302 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 247 HpackBlockCollector expected; | 226 HpackBlockCollector expected; |
| 248 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 227 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
| 249 8, false, "302"); | 228 8, false, "302"); |
| 250 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 229 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
| 251 24, false, "private"); | 230 24, false, "private"); |
| 252 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 231 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
| 253 33, false, | 232 33, false, |
| 254 "Mon, 21 Oct 2013 20:13:21 GMT"); | 233 "Mon, 21 Oct 2013 20:13:21 GMT"); |
| 255 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, | 234 expected.ExpectNameIndexAndLiteralValue(HpackEntryType::kIndexedLiteralHeader, |
| 256 46, false, "https://www.example.com"); | 235 46, false, "https://www.example.com"); |
| 257 NoArgValidator do_check = base::Bind(&HpackBlockDecoderTest::VerifyExpected, | 236 NoArgValidator do_check = [expected, this]() { |
| 258 base::Unretained(this), expected); | 237 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); |
| 238 }; |
| 259 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( | 239 EXPECT_TRUE(DecodeHpackExampleAndValidateSeveralWays( |
| 260 example, ValidateDoneAndEmpty(do_check))); | 240 example, ValidateDoneAndEmpty(do_check))); |
| 261 EXPECT_TRUE(do_check.Run()); | 241 EXPECT_TRUE(do_check()); |
| 262 } | 242 } |
| 263 | 243 |
| 264 // Generate a bunch of HPACK block entries to expect, use those expectations | 244 // Generate a bunch of HPACK block entries to expect, use those expectations |
| 265 // to generate an HPACK block, then decode it and confirm it matches those | 245 // to generate an HPACK block, then decode it and confirm it matches those |
| 266 // expectations. Some of these are invalid (such as Indexed, with index=0), | 246 // expectations. Some of these are invalid (such as Indexed, with index=0), |
| 267 // but well-formed, and the decoder doesn't check for validity, just | 247 // but well-formed, and the decoder doesn't check for validity, just |
| 268 // well-formedness. That includes the validity of the strings not being checked, | 248 // well-formedness. That includes the validity of the strings not being checked, |
| 269 // such as lower-case ascii for the names, and valid Huffman encodings. | 249 // such as lower-case ascii for the names, and valid Huffman encodings. |
| 270 TEST_F(HpackBlockDecoderTest, Computed) { | 250 TEST_F(HpackBlockDecoderTest, Computed) { |
| 271 HpackBlockCollector expected; | 251 HpackBlockCollector expected; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 296 value_huffman, Rand8String()); | 276 value_huffman, Rand8String()); |
| 297 expected.ExpectLiteralNameAndValue(type, true, Rand8String(), | 277 expected.ExpectLiteralNameAndValue(type, true, Rand8String(), |
| 298 value_huffman, Rand8String()); | 278 value_huffman, Rand8String()); |
| 299 } | 279 } |
| 300 } | 280 } |
| 301 // Shuffle the entries and serialize them to produce an HPACK block. | 281 // Shuffle the entries and serialize them to produce an HPACK block. |
| 302 expected.ShuffleEntries(RandomPtr()); | 282 expected.ShuffleEntries(RandomPtr()); |
| 303 HpackBlockBuilder hbb; | 283 HpackBlockBuilder hbb; |
| 304 expected.AppendToHpackBlockBuilder(&hbb); | 284 expected.AppendToHpackBlockBuilder(&hbb); |
| 305 | 285 |
| 306 NoArgValidator do_check = base::Bind(&HpackBlockDecoderTest::VerifyExpected, | 286 NoArgValidator do_check = [expected, this]() { |
| 307 base::Unretained(this), expected); | 287 VERIFY_AND_RETURN_SUCCESS(collector_.VerifyEq(expected)); |
| 288 }; |
| 308 EXPECT_TRUE( | 289 EXPECT_TRUE( |
| 309 DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check))); | 290 DecodeAndValidateSeveralWays(hbb, ValidateDoneAndEmpty(do_check))); |
| 310 EXPECT_TRUE(do_check.Run()); | 291 EXPECT_TRUE(do_check()); |
| 311 } | 292 } |
| 312 | 293 |
| 313 } // namespace | 294 } // namespace |
| 314 } // namespace test | 295 } // namespace test |
| 315 } // namespace net | 296 } // namespace net |
| OLD | NEW |