15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 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/quic/quic_headers_stream.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_utils.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/spdy_utils.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_connection_peer.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_session_peer.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/quic/test_tools/reliable_quic_stream_peer.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/spdy/spdy_protocol.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::StringPiece; 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::string; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::Invoke; 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::StrictMock; 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::WithArgs; 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::_; 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net { 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace test { 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockVisitor : public SpdyFramerVisitorInterface { 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD1(OnError, void(SpdyFramer* framer)); 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId stream_id, 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t length, 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin)); 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id, 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* data, 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t len, 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin)); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD3(OnControlFrameHeaderData, bool(SpdyStreamId stream_id, 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* header_data, 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t len)); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD5(OnSynStream, void(SpdyStreamId stream_id, 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyStreamId associated_stream_id, 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyPriority priority, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin, 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool unidirectional)); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD2(OnSynReply, void(SpdyStreamId stream_id, bool fin)); 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD2(OnRstStream, void(SpdyStreamId stream_id, 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyRstStreamStatus status)); 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD1(OnSettings, void(bool clear_persisted)); 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD3(OnSetting, void(SpdySettingsIds id, uint8 flags, uint32 value)); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD0(OnSettingsAck, void()); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD0(OnSettingsEnd, void()); 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack)); 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD2(OnGoAway, void(SpdyStreamId last_accepted_stream_id, 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyGoAwayStatus status)); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD3(OnHeaders, void(SpdyStreamId stream_id, bool fin, bool end)); 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId stream_id, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 delta_window_size)); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD2(OnCredentialFrameData, bool(const char* credential_data, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t len)); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOCK_METHOD1(OnBlocked, void(SpdyStreamId stream_id)); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD3(OnPushPromise, void(SpdyStreamId stream_id, 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyStreamId promised_stream_id, 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool end)); 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MOCK_METHOD2(OnContinuation, void(SpdyStreamId stream_id, bool end)); 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MOCK_METHOD6(OnAltSvc, void(SpdyStreamId stream_id, 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 max_age, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint16 port, 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StringPiece protocol_id, 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StringPiece host, 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) StringPiece origin)); 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type)); 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicHeadersStreamTest : public ::testing::TestWithParam<bool> { 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static QuicVersionVector GetVersions() { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicVersionVector versions; 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu versions.push_back(QuicVersionMax()); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return versions; 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicHeadersStreamTest() 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : connection_(new StrictMock<MockConnection>(is_server(), GetVersions())), 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_(connection_), 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_(QuicSessionPeer::GetHeadersStream(&session_)), 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) body_("hello world"), 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) framer_(SPDY3) { 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_[":version"] = "HTTP/1.1"; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_[":status"] = "200 Ok"; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_["content-length"] = "11"; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) framer_.set_visitor(&visitor_); 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(QuicVersionMax(), session_.connection()->version()); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(headers_stream_ != NULL); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConsumedData SaveIov(const IOVector& data) { 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const iovec* iov = data.iovec(); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int count = data.Capacity(); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0 ; i < count; ++i) { 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_data_.append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return QuicConsumedData(saved_data_.length(), false); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool SaveHeaderData(const char* data, int len) { 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_header_data_.append(data, len); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SaveHeaderDataStringPiece(StringPiece data) { 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_header_data_.append(data.data(), data.length()); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void WriteHeadersAndExpectSynStream(QuicStreamId stream_id, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPriority priority) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WriteHeadersAndCheckData(stream_id, fin, priority, SYN_STREAM); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void WriteHeadersAndExpectSynReply(QuicStreamId stream_id, 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WriteHeadersAndCheckData(stream_id, fin, 0, SYN_REPLY); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void WriteHeadersAndCheckData(QuicStreamId stream_id, 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin, 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPriority priority, 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyFrameType type) { 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Write the headers and capture the outgoing data 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_CALL(session_, WritevData(kHeadersStreamId, _, _, false, _, NULL)) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .WillOnce(WithArgs<1>(Invoke(this, &QuicHeadersStreamTest::SaveIov))); 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) headers_stream_->WriteHeaders(stream_id, headers_, fin, NULL); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Parse the outgoing data and check that it matches was was written. 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (type == SYN_STREAM) { 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(visitor_, OnSynStream(stream_id, kNoAssociatedStream, 0, 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // priority, 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fin, kNotUnidirectional)); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(visitor_, OnSynReply(stream_id, fin)); 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(visitor_, OnControlFrameHeaderData(stream_id, _, _)) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillRepeatedly(WithArgs<1, 2>( 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Invoke(this, &QuicHeadersStreamTest::SaveHeaderData))); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin) { 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(visitor_, OnStreamFrameData(stream_id, NULL, 0, true)); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) framer_.ProcessInput(saved_data_.data(), saved_data_.length()); 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_FALSE(framer_.HasError()) << framer_.error_code(); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckHeaders(); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_data_.clear(); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CheckHeaders() { 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyHeaderBlock headers; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(saved_header_data_.length(), 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) framer_.ParseHeaderBlockInBuffer(saved_header_data_.data(), 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_header_data_.length(), 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &headers)); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(headers_, headers); 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) saved_header_data_.clear(); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_server() { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return GetParam(); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CloseConnection() { 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicConnectionPeer::CloseConnection(connection_); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const bool kNotUnidirectional = false; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const bool kNoAssociatedStream = false; 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StrictMock<MockConnection>* connection_; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StrictMock<MockSession> session_; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicHeadersStream* headers_stream_; 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyHeaderBlock headers_; 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string body_; 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string saved_data_; 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string saved_header_data_; 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyFramer framer_; 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StrictMock<MockVisitor> visitor_; 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(Tests, QuicHeadersStreamTest, testing::Bool()); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, StreamId) { 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(3u, headers_stream_->id()); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, EffectivePriority) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(0u, headers_stream_->EffectivePriority()); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, WriteHeaders) { 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (QuicStreamId stream_id = kClientDataStreamId1; 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_id < kClientDataStreamId3; stream_id += 2) { 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int count = 0; count < 2; ++count) { 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin = (count == 0); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_server()) { 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WriteHeadersAndExpectSynReply(stream_id, fin); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (QuicPriority priority = 0; priority < 7; ++priority) { 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WriteHeadersAndExpectSynStream(stream_id, fin, priority); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessRawData) { 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (QuicStreamId stream_id = kClientDataStreamId1; 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) stream_id < kClientDataStreamId3; stream_id += 2) { 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int count = 0; count < 2; ++count) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin = (count == 0); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (QuicPriority priority = 0; priority < 7; ++priority) { 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Replace with "WriteHeadersAndSaveData" 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame; 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_server()) { 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySynStreamIR syn_stream(stream_id); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_stream.set_name_value_block(headers_); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_stream.set_fin(fin); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame.reset(framer_.SerializeSynStream(syn_stream)); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)); 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySynReplyIR syn_reply(stream_id); 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_reply.set_name_value_block(headers_); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_reply.set_fin(fin); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame.reset(framer_.SerializeSynReply(syn_reply)); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(session_, OnStreamHeaders(stream_id, _)) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillRepeatedly(WithArgs<1>( 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Invoke(this, 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::SaveHeaderDataStringPiece))); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(session_, 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnStreamHeadersComplete(stream_id, fin, frame->size())); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CheckHeaders(); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) { 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyDataIR data(2, ""); 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY DATA frame received.")) 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) { 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR, ""); 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails( 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUIC_INVALID_HEADERS_STREAM_DATA, 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY RST_STREAM frame received.")) 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) { 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySettingsIR data; 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.AddSetting(SETTINGS_UPLOAD_BANDWIDTH, true, true, 0); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails( 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUIC_INVALID_HEADERS_STREAM_DATA, 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY SETTINGS frame received.")) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) { 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyPingIR data(1); 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY PING frame received.")) 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) { 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away"); 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY GOAWAY frame received.")) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyHeadersFrame) { 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyHeadersIR data(1); 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails(QUIC_INVALID_HEADERS_STREAM_DATA, 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY HEADERS frame received.")) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) { 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyWindowUpdateIR data(1, 1); 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame(framer_.SerializeFrame(data)); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_CALL(*connection_, 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendConnectionCloseWithDetails( 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUIC_INVALID_HEADERS_STREAM_DATA, 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY WINDOW_UPDATE frame received.")) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &QuicHeadersStreamTest::CloseConnection)); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_stream_->ProcessRawData(frame->data(), frame->size()); 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 328116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) { 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (connection_->version() < QUIC_VERSION_21) { 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(headers_stream_->flow_controller()->IsEnabled()); 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(headers_stream_->flow_controller()->IsEnabled()); 333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl( 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch headers_stream_)); 336e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 337e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace test 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace net 341