15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/spdy/spdy_headers_block_parser.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/sys_byteorder.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net { 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::IntToString; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::StringPiece; 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::string; 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::ElementsAre; 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::ElementsAreArray; 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A mock the handler class to check that we parse out the correct headers 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and call the callback methods when we should. 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockSpdyHeadersHandler : public SpdyHeadersHandlerInterface { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD2(OnHeaderBlock, void(SpdyStreamId stream_id, 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32_t num_of_headers)); 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MOCK_METHOD2(OnHeaderBlockEnd, void(SpdyStreamId stream_id, size_t bytes)); 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD3(OnHeader, void(SpdyStreamId stream_id, 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece, 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece)); 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class SpdyHeadersBlockParserTest : 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public ::testing::TestWithParam<SpdyMajorVersion> { 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~SpdyHeadersBlockParserTest() {} 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetUp() { 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create a parser using the mock handler. 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) spdy_version_ = GetParam(); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_)); 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) length_field_size_ = 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyHeadersBlockParser::LengthFieldSizeForVersion(spdy_version_); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create a header block with a specified number of headers. 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string CreateHeaders(uint32_t num_headers, bool insert_nulls) { 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string headers; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First, write the number of headers in the header block. 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) headers += EncodeLength(num_headers); 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Second, write the key-value pairs. 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (uint32_t i = 0; i < num_headers; i++) { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Build the key. 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string key; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (insert_nulls) { 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch key = string(kBaseKey) + string("\0", 1) + IntToString(i); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch key = string(kBaseKey) + IntToString(i); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Encode the key as SPDY header. 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) headers += EncodeLength(key.length()); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers += key; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Build the value. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string value; 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (insert_nulls) { 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch value = string(kBaseValue) + string("\0", 1) + IntToString(i); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch value = string(kBaseValue) + IntToString(i); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Encode the value as SPDY header. 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) headers += EncodeLength(value.length()); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers += value; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return headers; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string EncodeLength(uint32_t len) { 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) char buffer[4]; 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (length_field_size_ == sizeof(uint32_t)) { 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint32_t net_order_len = htonl(len); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) memcpy(buffer, &net_order_len, length_field_size_); 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (length_field_size_ == sizeof(uint16_t)) { 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint16_t net_order_len = htons(len); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) memcpy(buffer, &net_order_len, length_field_size_); 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(false) << "Invalid length field size"; 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return string(buffer, length_field_size_); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t length_field_size_; 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyMajorVersion spdy_version_; 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MockSpdyHeadersHandler handler_; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SpdyHeadersBlockParser> parser_; 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static const char *const kBaseKey; 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static const char *const kBaseValue; 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Number of headers and header blocks used in the tests. 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const int kNumHeadersInBlock = 10; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const int kNumHeaderBlocks = 10; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char *const SpdyHeadersBlockParserTest::kBaseKey = "test_key"; 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char *const SpdyHeadersBlockParserTest::kBaseValue = "test_value"; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// All tests are run with 3 different SPDY versions: SPDY/2, SPDY/3, SPDY/4. 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(SpdyHeadersBlockParserTests, 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyHeadersBlockParserTest, 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::testing::Values(SPDY2, SPDY3, SPDY4)); 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdyHeadersBlockParserTest, BasicTest) { 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sanity test, verify that we parse out correctly a block with 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a single key-value pair and that we notify when we start and finish 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // handling a headers block. 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) string headers(CreateHeaders(1, false)); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string expect_key = kBaseKey + IntToString(0); 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string expect_value = kBaseValue + IntToString(0); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece(expect_value))).Times(1); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1); 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(parser_-> 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdyHeadersBlockParserTest, NullsSupportedTest) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sanity test, verify that we parse out correctly a block with 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a single key-value pair when the key and value contain null charecters. 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) string headers(CreateHeaders(1, true)); 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string expect_key = kBaseKey + string("\0", 1) + IntToString(0); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string expect_value = kBaseValue + string("\0", 1) + IntToString(0); 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece(expect_value))).Times(1); 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(parser_-> 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdyHeadersBlockParserTest, MultipleBlocksAndHeadersWithPartialData) { 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) testing::InSequence s; 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // CreateHeaders is deterministic; we can call it once for the whole test. 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) string headers(CreateHeaders(kNumHeadersInBlock, false)); 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The mock doesn't retain storage of arguments, so keep them in scope. 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<string> retained_arguments; 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < kNumHeadersInBlock; i++) { 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch retained_arguments.push_back(kBaseKey + IntToString(i)); 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch retained_arguments.push_back(kBaseValue + IntToString(i)); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For each block we expect to parse out the headers in order. 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < kNumHeaderBlocks; i++) { 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlock(i, kNumHeadersInBlock)).Times(1); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int j = 0; j < kNumHeadersInBlock; j++) { 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeader( 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i, 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPiece(retained_arguments[2 * j]), 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPiece(retained_arguments[2 * j + 1]))).Times(1); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlockEnd(i, headers.length())).Times(1); 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Parse the header blocks, feeding the parser one byte at a time. 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < kNumHeaderBlocks; i++) { 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (string::iterator it = headers.begin(); it != headers.end(); ++it) { 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ((it + 1) == headers.end()) { 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Last byte completes the block. 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(parser_->HandleControlFrameHeadersData(i, &(*it), 1)); 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(parser_->HandleControlFrameHeadersData(i, &(*it), 1)); 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdyHeadersBlockParserTest, HandlesEmptyCallsTest) { 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) string headers(CreateHeaders(1, false)); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch string expect_key = kBaseKey + IntToString(0); 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch string expect_value = kBaseValue + IntToString(0); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece(expect_value))).Times(1); 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Send a header in pieces with intermediate empty calls. 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (string::iterator it = headers.begin(); it != headers.end(); ++it) { 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ((it + 1) == headers.end()) { 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Last byte completes the block. 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::OK, parser_->get_error()); 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, &(*it), 1)); 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, NULL, 0)); 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdyHeadersBlockParserTest, LargeBlocksDiscardedTest) { 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Header block with too many headers. 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string headers = EncodeLength( 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parser_->MaxNumberOfHeadersForVersion(spdy_version_) + 1); 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(parser_-> 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::HEADER_BLOCK_TOO_LARGE, 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parser_->get_error()); 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parser_->Reset(); 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Header block with one header, which has a too-long key. 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string headers = EncodeLength(1) + EncodeLength( 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyHeadersBlockParser::kMaximumFieldLength + 1); 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(parser_-> 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::HEADER_FIELD_TOO_LARGE, 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parser_->get_error()); 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_P(SpdyHeadersBlockParserTest, ExtraDataTest) { 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) string headers = CreateHeaders(1, false) + "foobar"; 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1); 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1); 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch string expect_key = kBaseKey + IntToString(0); 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch string expect_value = kBaseValue + IntToString(0); 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key), 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece(expect_value))).Times(1); 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(parser_-> 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HandleControlFrameHeadersData(1, headers.c_str(), headers.length())); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SpdyHeadersBlockParser::TOO_MUCH_DATA, parser_->get_error()); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace net 260