1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_reliable_server_stream.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/quic_spdy_compressor.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_utils.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/flip_server/epoll_server.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_in_memory_cache.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_spdy_server_stream.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/spdy_utils.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/test_tools/quic_test_utils.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::StringPiece; 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::tools::test::MockConnection; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::test::MockSession; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using std::string; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::_; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::AnyNumber; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::Invoke; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::InvokeArgument; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::InSequence; 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::Return; 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::StrEq; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::StrictMock; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::WithArgs; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test { 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicReliableServerStreamPeer { 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static BalsaHeaders* GetMutableHeaders( 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicReliableServerStream* stream) { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return &(stream->headers_); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicReliableServerStreamTest : public ::testing::Test { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicReliableServerStreamTest() 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : session_(new MockConnection(1, IPEndPoint(), 0, &eps_, true), true), 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) body_("hello world") { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BalsaHeaders request_headers; 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_headers.SetRequestFirstlineFromStringPieces( 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "POST", "https://www.google.com/", "HTTP/1.1"); 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_headers.ReplaceOrAppendHeader("content-length", "11"); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) headers_string_ = SpdyUtils::SerializeRequestHeaders(request_headers); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_.reset(new QuicSpdyServerStream(3, &session_)); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicConsumedData ValidateHeaders(StringPiece headers) { 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) headers_string_ = SpdyUtils::SerializeResponseHeaders( 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers_); 64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) QuicSpdyDecompressor decompressor; 65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) TestDecompressorVisitor visitor; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // First the header id, then the compressed data. 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(1, headers[0]); 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(0, headers[1]); 70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(0, headers[2]); 71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(0, headers[3]); 72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(static_cast<size_t>(headers.length() - 4), 73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) decompressor.DecompressData(headers.substr(4), &visitor)); 74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) EXPECT_EQ(headers_string_, visitor.data()); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return QuicConsumedData(headers.size(), false); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static void SetUpTestCase() { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicInMemoryCache::GetInstance()->ResetForTests(); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicInMemoryCache* cache = QuicInMemoryCache::GetInstance(); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BalsaHeaders request_headers, response_headers; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece body("Yum"); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_headers.SetRequestFirstlineFromStringPieces( 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "GET", 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "https://www.google.com/foo", 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "HTTP/1.1"); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers.SetRequestFirstlineFromStringPieces("HTTP/1.1", 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "200", 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "OK"); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers.AppendHeader("content-length", 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::IntToString(body.length())); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if response already exists and matches. 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const QuicInMemoryCache::Response* cached_response = 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache->GetResponse(request_headers); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cached_response != NULL) { 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string cached_response_headers_str, response_headers_str; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cached_response->headers().DumpToString(&cached_response_headers_str); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers.DumpToString(&response_headers_str); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(cached_response_headers_str, response_headers_str); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(cached_response->body(), body); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache->AddResponse(request_headers, response_headers, body); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BalsaHeaders response_headers_; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer eps_; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StrictMock<MockSession> session_; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<QuicReliableServerStream> stream_; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string headers_string_; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string body_; 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicConsumedData ConsumeAllData(QuicStreamId id, StringPiece data, 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicStreamOffset offset, bool fin) { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return QuicConsumedData(data.size(), fin); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicReliableServerStreamTest, TestFraming) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, _, _, _)).Times(AnyNumber()). 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WillRepeatedly(Invoke(ConsumeAllData)); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(headers_string_.size(), stream_->ProcessData( 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) headers_string_.c_str(), headers_string_.size())); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(body_.size(), stream_->ProcessData(body_.c_str(), body_.size())); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(11u, stream_->headers().content_length()); 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("https://www.google.com/", stream_->headers().request_uri()); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("POST", stream_->headers().request_method()); 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(body_, stream_->body()); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicReliableServerStreamTest, TestFramingOnePacket) { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, _, _, _)).Times(AnyNumber()). 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WillRepeatedly(Invoke(ConsumeAllData)); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string message = headers_string_ + body_; 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(message.size(), stream_->ProcessData( 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message.c_str(), message.size())); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(11u, stream_->headers().content_length()); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("https://www.google.com/", 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_->headers().request_uri()); 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("POST", stream_->headers().request_method()); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(body_, stream_->body()); 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicReliableServerStreamTest, TestFramingExtraData) { 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string large_body = "hello world!!!!!!"; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We'll automatically write out an error (headers + body) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, _, _, _)).Times(2). 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WillRepeatedly(Invoke(ConsumeAllData)); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(headers_string_.size(), stream_->ProcessData( 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) headers_string_.c_str(), headers_string_.size())); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Content length is still 11. This will register as an error and we won't 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // accept the bytes. 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_->ProcessData(large_body.c_str(), large_body.size()); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_->TerminateFromPeer(true); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(11u, stream_->headers().content_length()); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("https://www.google.com/", stream_->headers().request_uri()); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("POST", stream_->headers().request_method()); 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicReliableServerStreamTest, TestSendResponse) { 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BalsaHeaders* request_headers = 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicReliableServerStreamPeer::GetMutableHeaders(stream_.get()); 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_headers->SetRequestFirstlineFromStringPieces( 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "GET", 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "https://www.google.com/foo", 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "HTTP/1.1"); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers_.SetResponseFirstlineFromStringPieces( 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "HTTP/1.1", "200", "OK"); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers_.ReplaceOrAppendHeader("content-length", "3"); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, _, _, _)).Times(1) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(WithArgs<1>(Invoke( 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, &QuicReliableServerStreamTest::ValidateHeaders))); 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece kBody = "Yum"; 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, kBody, _, _)).Times(1). 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WillOnce(Return(QuicConsumedData(3, true))); 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_->SendResponse(); 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(stream_->read_side_closed()); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(stream_->write_side_closed()); 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicReliableServerStreamTest, TestSendErrorResponse) { 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers_.SetResponseFirstlineFromStringPieces( 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "HTTP/1.1", "500", "Server Error"); 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) response_headers_.ReplaceOrAppendHeader("content-length", "3"); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, _, _, _)).Times(1) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(WithArgs<1>(Invoke( 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, &QuicReliableServerStreamTest::ValidateHeaders))); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringPiece kBody = "bad"; 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(session_, WriteData(_, kBody, _, _)).Times(1). 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WillOnce(Return(QuicConsumedData(3, true))); 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream_->SendErrorResponse(); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(stream_->read_side_closed()); 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(stream_->write_side_closed()); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace test 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace tools 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 220