blob: 108e9e0d74d42e0cef633492b7c8db410e586580 [file] [log] [blame]
[email protected]f702d572012-12-04 15:56:201// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/quic/quic_http_stream.h"
6
sclittle1edeeb22015-09-02 20:46:107#include <stdint.h>
8
[email protected]f702d572012-12-04 15:56:209#include <vector>
10
skyostil4891b25b2015-06-11 11:43:4511#include "base/thread_task_runner_handle.h"
mmenkecbc2b712014-10-09 20:29:0712#include "net/base/chunked_upload_data_stream.h"
13#include "net/base/elements_upload_data_stream.h"
[email protected]f702d572012-12-04 15:56:2014#include "net/base/net_errors.h"
tbansalfdf5665b2015-09-21 22:46:4015#include "net/base/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2016#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0617#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2018#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1519#include "net/http/transport_security_state.h"
[email protected]fee17f72013-02-03 07:47:4120#include "net/quic/congestion_control/send_algorithm_interface.h"
[email protected]e8ff26842013-03-22 21:02:0521#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1622#include "net/quic/crypto/quic_decrypter.h"
23#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0424#include "net/quic/crypto/quic_server_info.h"
ckrasic4f9d88d2015-07-22 22:23:1625#include "net/quic/quic_chromium_client_session.h"
[email protected]f702d572012-12-04 15:56:2026#include "net/quic/quic_connection.h"
27#include "net/quic/quic_connection_helper.h"
[email protected]cbd731e2013-10-24 00:20:3928#include "net/quic/quic_default_packet_writer.h"
[email protected]24e5bc52013-09-18 15:36:5829#include "net/quic/quic_http_utils.h"
rtenneti1cd3b162015-09-29 02:58:2830#include "net/quic/quic_packet_reader.h"
[email protected]24e5bc52013-09-18 15:36:5831#include "net/quic/quic_reliable_client_stream.h"
[email protected]9f0dcd4e2014-01-16 15:58:1432#include "net/quic/quic_write_blocked_list.h"
[email protected]3e7dca62013-09-10 16:14:2333#include "net/quic/spdy_utils.h"
rch1fe2eeb2015-10-26 14:45:5734#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]f702d572012-12-04 15:56:2035#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0536#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0337#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3938#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2039#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2040#include "net/quic/test_tools/quic_test_utils.h"
41#include "net/quic/test_tools/test_task_runner.h"
42#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3643#include "net/spdy/spdy_frame_builder.h"
44#include "net/spdy/spdy_framer.h"
45#include "net/spdy/spdy_http_utils.h"
46#include "net/spdy/spdy_protocol.h"
[email protected]f702d572012-12-04 15:56:2047#include "testing/gmock/include/gmock/gmock.h"
48#include "testing/gtest/include/gtest/gtest.h"
49
50using testing::_;
[email protected]06ff5152013-08-29 01:03:0551using testing::AnyNumber;
52using testing::Return;
[email protected]f702d572012-12-04 15:56:2053
54namespace net {
[email protected]f702d572012-12-04 15:56:2055namespace test {
[email protected]f702d572012-12-04 15:56:2056namespace {
57
[email protected]16ba7742014-08-22 00:57:2558const char kUploadData[] = "Really nifty data!";
bncb07c05532015-05-14 19:07:2059const char kDefaultServerHostName[] = "www.google.com";
60const uint16 kDefaultServerPort = 80;
[email protected]f702d572012-12-04 15:56:2061
62class TestQuicConnection : public QuicConnection {
63 public:
[email protected]1e960032013-12-20 19:00:2064 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4365 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2066 IPEndPoint address,
[email protected]cbd731e2013-10-24 00:20:3967 QuicConnectionHelper* helper,
[email protected]6d515822014-08-22 01:58:0668 const QuicConnection::PacketWriterFactory& writer_factory)
[email protected]66cd2d62014-08-01 18:42:3969 : QuicConnection(connection_id,
70 address,
71 helper,
[email protected]6d515822014-08-22 01:58:0672 writer_factory,
rtenneti6f48aa92015-03-16 02:18:4873 true /* owns_writer */,
74 Perspective::IS_CLIENT,
rtenneti6f48aa92015-03-16 02:18:4875 versions) {}
[email protected]f702d572012-12-04 15:56:2076
[email protected]fee17f72013-02-03 07:47:4177 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
78 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2079 }
80};
81
[email protected]63534512012-12-23 18:49:0082// Subclass of QuicHttpStream that closes itself when the first piece of data
83// is received.
84class AutoClosingStream : public QuicHttpStream {
85 public:
ckrasic4f9d88d2015-07-22 22:23:1686 explicit AutoClosingStream(
87 const base::WeakPtr<QuicChromiumClientSession>& session)
88 : QuicHttpStream(session) {}
[email protected]63534512012-12-23 18:49:0089
sclittlec4dc1a32015-09-24 00:15:4590 void OnHeadersAvailable(const SpdyHeaderBlock& headers,
91 size_t frame_len) override {
[email protected]63534512012-12-23 18:49:0092 Close(false);
[email protected]63534512012-12-23 18:49:0093 }
rchb27683c2015-07-29 23:53:5094
95 void OnDataAvailable() override { Close(false); }
[email protected]63534512012-12-23 18:49:0096};
97
[email protected]6d515822014-08-22 01:58:0698class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
99 public:
100 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
101 : socket_(socket) {}
dchengb03027d2014-10-21 12:00:20102 ~TestPacketWriterFactory() override {}
[email protected]6d515822014-08-22 01:58:06103
dchengb03027d2014-10-21 12:00:20104 QuicPacketWriter* Create(QuicConnection* connection) const override {
[email protected]6d515822014-08-22 01:58:06105 return new QuicDefaultPacketWriter(socket_);
106 }
107
108 private:
109 DatagramClientSocket* socket_;
110};
111
[email protected]f702d572012-12-04 15:56:20112} // namespace
113
[email protected]24e5bc52013-09-18 15:36:58114class QuicHttpStreamPeer {
115 public:
116 static QuicReliableClientStream* GetQuicReliableClientStream(
117 QuicHttpStream* stream) {
118 return stream->stream_;
119 }
120};
121
[email protected]1e960032013-12-20 19:00:20122class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20123 protected:
[email protected]1e960032013-12-20 19:00:20124 static const bool kFin = true;
125 static const bool kIncludeVersion = true;
126 static const bool kIncludeCongestionFeedback = true;
127
[email protected]f702d572012-12-04 15:56:20128 // Holds a packet to be written to the wire, and the IO mode that should
129 // be used by the mock socket when performing the write.
130 struct PacketToWrite {
131 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
132 : mode(mode),
133 packet(packet) {
134 }
135 IoMode mode;
136 QuicEncryptedPacket* packet;
137 };
138
139 QuicHttpStreamTest()
140 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00141 use_closing_stream_(false),
rch1fe2eeb2015-10-26 14:45:57142 crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
[email protected]f702d572012-12-04 15:56:20143 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43144 connection_id_(2),
[email protected]66ae5962014-05-22 11:13:05145 stream_id_(kClientDataStreamId1),
bncb07c05532015-05-14 19:07:20146 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
[email protected]1e960032013-12-20 19:00:20147 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20148 IPAddressNumber ip;
149 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
150 peer_addr_ = IPEndPoint(ip, 443);
151 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43152 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20153 }
154
155 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19156 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20157 for (size_t i = 0; i < writes_.size(); i++) {
158 delete writes_[i].packet;
159 }
160 }
161
162 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20163 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
164 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20165 }
166
167 // Returns the packet to be written at position |pos|.
168 QuicEncryptedPacket* GetWrite(size_t pos) {
169 return writes_[pos].packet;
170 }
171
172 bool AtEof() {
rch37de576c2015-05-17 20:28:17173 return socket_data_->AllReadDataConsumed() &&
174 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20175 }
176
[email protected]1e960032013-12-20 19:00:20177 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
178 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20179 }
180
181 // Configures the test fixture to use the list of expected writes.
182 void Initialize() {
183 mock_writes_.reset(new MockWrite[writes_.size()]);
184 for (size_t i = 0; i < writes_.size(); i++) {
185 mock_writes_[i] = MockWrite(writes_[i].mode,
186 writes_[i].packet->data(),
187 writes_[i].packet->length());
188 };
189
rtennetibe635732014-10-02 22:51:42190 socket_data_.reset(new StaticSocketDataProvider(
191 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20192
[email protected]e13201d82012-12-12 05:00:32193 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
194 net_log_.net_log());
195 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20196 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41197 send_algorithm_ = new MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57198 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
199 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
[email protected]efecff92013-09-24 07:49:23200 EXPECT_CALL(*send_algorithm_,
[email protected]ef0da582014-05-09 07:16:30201 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07202 EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
203 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
204 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
205 .WillRepeatedly(Return(kMaxPacketSize));
206 EXPECT_CALL(*send_algorithm_, PacingRate())
207 .WillRepeatedly(Return(QuicBandwidth::Zero()));
208 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
209 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
210 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
211 .WillRepeatedly(Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40212 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44213 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
214 &random_generator_));
[email protected]6d515822014-08-22 01:58:06215 TestPacketWriterFactory writer_factory(socket);
[email protected]3aa9ca72014-02-27 19:39:43216 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
217 connection_id_, peer_addr_,
[email protected]6d515822014-08-22 01:58:06218 helper_.get(), writer_factory);
[email protected]f702d572012-12-04 15:56:20219 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41220 connection_->SetSendAlgorithm(send_algorithm_);
ckrasic4f9d88d2015-07-22 22:23:16221 session_.reset(new QuicChromiumClientSession(
rtennetid39bd762015-06-12 01:05:52222 connection_, scoped_ptr<DatagramClientSocket>(socket),
rtenneti1cd3b162015-09-29 02:58:28223 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
rtenneti041b2992015-02-23 23:03:28224 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
bncb07c05532015-05-14 19:07:20225 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
rch1fe2eeb2015-10-26 14:45:57226 PRIVACY_MODE_DISABLED),
rtenneti1cd3b162015-09-29 02:58:28227 kQuicYieldAfterPacketsRead,
228 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
rtennetia75df622015-06-21 23:59:50229 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
230 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
tbansalfdf5665b2015-09-21 22:46:40231 base::ThreadTaskRunnerHandle::Get().get(),
232 /*socket_performance_watcher=*/nullptr, nullptr));
rtennetid39bd762015-06-12 01:05:52233 session_->Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44234 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48235 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36236 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36237 new AutoClosingStream(session_->GetWeakPtr()) :
238 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36239 }
240
[email protected]1e960032013-12-20 19:00:20241 void SetRequest(const std::string& method,
242 const std::string& path,
243 RequestPriority priority) {
244 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36245 }
246
[email protected]1e960032013-12-20 19:00:20247 void SetResponse(const std::string& status, const std::string& body) {
248 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03249 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36250 }
[email protected]f702d572012-12-04 15:56:20251
[email protected]1e960032013-12-20 19:00:20252 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
rtennetia004d332015-08-28 06:44:57253 QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05254 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20255 bool fin,
256 QuicStreamOffset offset,
257 base::StringPiece data) {
rtennetia004d332015-08-28 06:44:57258 return maker_.MakeDataPacket(packet_number, stream_id_,
rtennetif4bdb542015-01-21 14:33:05259 should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20260 }
261
[email protected]1e960032013-12-20 19:00:20262 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
rtennetia004d332015-08-28 06:44:57263 QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05264 bool fin,
sclittlec4dc1a32015-09-24 00:15:45265 RequestPriority request_priority,
266 size_t* spdy_headers_frame_length) {
rtennetif4bdb542015-01-21 14:33:05267 QuicPriority priority =
268 ConvertRequestPriorityToQuicPriority(request_priority);
sclittlec4dc1a32015-09-24 00:15:45269 return maker_.MakeRequestHeadersPacket(
270 packet_number, stream_id_, kIncludeVersion, fin, priority,
271 request_headers_, spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20272 }
273
274 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
rtennetia004d332015-08-28 06:44:57275 QuicPacketNumber packet_number,
sclittlec4dc1a32015-09-24 00:15:45276 bool fin,
277 size_t* spdy_headers_frame_length) {
[email protected]1e960032013-12-20 19:00:20278 return maker_.MakeResponseHeadersPacket(
sclittlec4dc1a32015-09-24 00:15:45279 packet_number, stream_id_, !kIncludeVersion, fin, response_headers_,
280 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20281 }
282
283 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
rtennetia004d332015-08-28 06:44:57284 QuicPacketNumber packet_number) {
[email protected]1e960032013-12-20 19:00:20285 return maker_.MakeRstPacket(
rtennetia004d332015-08-28 06:44:57286 packet_number, true, stream_id_,
rtenneti4a5df262014-11-07 00:43:58287 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
[email protected]06ff5152013-08-29 01:03:05288 }
289
rtenneti6bd660b2015-07-18 00:19:53290 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
rtennetia004d332015-08-28 06:44:57291 QuicPacketNumber packet_number) {
292 return maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
rtenneti6bd660b2015-07-18 00:19:53293 QUIC_STREAM_CANCELLED);
294 }
295
[email protected]c5e1aca2014-01-30 04:03:04296 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
rtennetia004d332015-08-28 06:44:57297 QuicPacketNumber packet_number) {
298 return maker_.MakeAckAndRstPacket(packet_number, !kIncludeVersion,
299 stream_id_, QUIC_STREAM_CANCELLED, 2, 1,
300 !kIncludeCongestionFeedback);
[email protected]c5e1aca2014-01-30 04:03:04301 }
302
[email protected]1e960032013-12-20 19:00:20303 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
rtennetia004d332015-08-28 06:44:57304 QuicPacketNumber packet_number,
305 QuicPacketNumber largest_received,
306 QuicPacketNumber least_unacked) {
307 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
308 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00309 }
310
[email protected]f702d572012-12-04 15:56:20311 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00312 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41313 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20314 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17315 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20316 MockClock clock_;
317 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44318 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20319 testing::StrictMock<MockConnectionVisitor> visitor_;
320 scoped_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15321 TransportSecurityState transport_security_state_;
ckrasic4f9d88d2015-07-22 22:23:16322 scoped_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01323 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20324 TestCompletionCallback callback_;
325 HttpRequestInfo request_;
326 HttpRequestHeaders headers_;
327 HttpResponseInfo response_;
328 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20329 SpdyHeaderBlock request_headers_;
330 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36331 std::string request_data_;
332 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20333
334 private:
[email protected]3aa9ca72014-02-27 19:39:43335 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20336 const QuicStreamId stream_id_;
337 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20338 IPEndPoint self_addr_;
339 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58340 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05341 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20342 scoped_ptr<StaticSocketDataProvider> socket_data_;
343 std::vector<PacketToWrite> writes_;
344};
345
[email protected]1e960032013-12-20 19:00:20346INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
347 ::testing::ValuesIn(QuicSupportedVersions()));
348
349TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44350 Initialize();
rtennetibe635732014-10-02 22:51:42351 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20352}
353
mmenkebd84c392015-09-02 14:12:34354TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44355 Initialize();
mmenkebd84c392015-09-02 14:12:34356 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20357}
358
[email protected]1e960032013-12-20 19:00:20359TEST_P(QuicHttpStreamTest, GetRequest) {
360 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45361 size_t spdy_request_header_frame_length;
362 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
363 &spdy_request_header_frame_length));
[email protected]f702d572012-12-04 15:56:20364 Initialize();
365
366 request_.method = "GET";
367 request_.url = GURL("http://www.google.com/");
368
[email protected]262eec82013-03-19 21:01:36369 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
370 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20371 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
372 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20373
374 // Ack the request.
[email protected]1e960032013-12-20 19:00:20375 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20376
377 EXPECT_EQ(ERR_IO_PENDING,
378 stream_->ReadResponseHeaders(callback_.callback()));
379
[email protected]1e960032013-12-20 19:00:20380 SetResponse("404 Not Found", std::string());
sclittlec4dc1a32015-09-24 00:15:45381 size_t spdy_response_header_frame_length;
382 ProcessPacket(ConstructResponseHeadersPacket(
383 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20384
385 // Now that the headers have been processed, the callback will return.
386 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36387 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20388 EXPECT_EQ(404, response_.headers->response_code());
389 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53390 EXPECT_FALSE(response_.response_time.is_null());
391 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20392
393 // There is no body, so this should return immediately.
394 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
395 read_buffer_->size(),
396 callback_.callback()));
397 EXPECT_TRUE(stream_->IsResponseBodyComplete());
398 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10399
400 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45401 // headers and payload.
402 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
403 stream_->GetTotalSentBytes());
404 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
405 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20406}
407
[email protected]3e7dca62013-09-10 16:14:23408// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20409TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
410 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45411 size_t spdy_request_headers_frame_length;
412 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
413 &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23414 Initialize();
415
416 request_.method = "GET";
417 request_.url = GURL("http://www.google.com/");
418
419 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
420 net_log_, callback_.callback()));
421 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
422 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23423
424 // Ack the request.
[email protected]1e960032013-12-20 19:00:20425 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23426
427 EXPECT_EQ(ERR_IO_PENDING,
428 stream_->ReadResponseHeaders(callback_.callback()));
429
430 SpdyHeaderBlock headers;
431 headers[":status"] = "200 OK";
432 headers[":version"] = "HTTP/1.1";
433 headers["content-type"] = "text/plain";
rch7dd15702015-07-01 18:57:57434 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23435
rch7dd15702015-07-01 18:57:57436 response_headers_ = headers;
sclittlec4dc1a32015-09-24 00:15:45437 size_t spdy_response_headers_frame_length;
438 ProcessPacket(ConstructResponseHeadersPacket(
439 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23440
441 // Now that the headers have been processed, the callback will return.
442 EXPECT_EQ(OK, callback_.WaitForResult());
443 ASSERT_TRUE(response_.headers.get());
444 EXPECT_EQ(200, response_.headers->response_code());
445 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
446
447 // There is no body, so this should return immediately.
448 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
449 read_buffer_->size(),
450 callback_.callback()));
451 EXPECT_TRUE(stream_->IsResponseBodyComplete());
452 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10453
454 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45455 // headers and payload.
456 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
457 stream_->GetTotalSentBytes());
458 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
459 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:23460}
461
rchf9f103cbc2014-08-30 05:28:04462// Regression test for http://crbug.com/409101
463TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
464 SetRequest("GET", "/", DEFAULT_PRIORITY);
465 Initialize();
466
467 request_.method = "GET";
468 request_.url = GURL("http://www.google.com/");
469
470 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
471 net_log_, callback_.callback()));
472
473 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
474
475 EXPECT_EQ(ERR_CONNECTION_CLOSED,
476 stream_->SendRequest(headers_, &response_,
477 callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10478
479 EXPECT_EQ(0, stream_->GetTotalSentBytes());
480 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:04481}
482
rch11a114a2014-09-04 23:41:59483// Regression test for http://crbug.com/409871
484TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
485 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45486 size_t spdy_request_headers_frame_length;
487 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
488 &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:59489 Initialize();
490
491 request_.method = "GET";
492 request_.url = GURL("http://www.google.com/");
493
494 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
495 net_log_, callback_.callback()));
496
497 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
498 callback_.callback()));
499
500 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
501
502 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10503
504 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45505 // headers and payload.
506 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
507 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:10508 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:59509}
510
[email protected]1e960032013-12-20 19:00:20511TEST_P(QuicHttpStreamTest, SendPostRequest) {
512 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45513 size_t spdy_request_headers_frame_length;
514 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
515 &spdy_request_headers_frame_length));
[email protected]92bf17c2014-03-03 21:14:03516 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20517 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20518
519 Initialize();
520
[email protected]b2d26cfd2012-12-11 10:36:06521 ScopedVector<UploadElementReader> element_readers;
522 element_readers.push_back(
523 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
mmenkecbc2b712014-10-09 20:29:07524 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20525 request_.method = "POST";
526 request_.url = GURL("http://www.google.com/");
527 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24528 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20529
[email protected]262eec82013-03-19 21:01:36530 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
531 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20532 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
533 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20534
535 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20536 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20537
538 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20539 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45540 size_t spdy_response_headers_frame_length;
541 ProcessPacket(ConstructResponseHeadersPacket(
542 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:20543
rchb27683c2015-07-29 23:53:50544 // The headers have arrived, but they are delivered asynchronously.
545 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
546 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36547 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20548 EXPECT_EQ(200, response_.headers->response_code());
549 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
550
551 // Send the response body.
552 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03553 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20554 // Since the body has already arrived, this should return immediately.
555 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
556 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
557 callback_.callback()));
558
559 EXPECT_TRUE(stream_->IsResponseBodyComplete());
560 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10561
562 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45563 // headers and payload.
564 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
565 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:10566 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:45567 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
568 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10569 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20570}
571
[email protected]1e960032013-12-20 19:00:20572TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
573 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47574 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:45575 size_t spdy_request_headers_frame_length;
576 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
577 &spdy_request_headers_frame_length));
[email protected]92bf17c2014-03-03 21:14:03578 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
579 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
580 kUploadData));
[email protected]1e960032013-12-20 19:00:20581 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47582 Initialize();
583
mmenkecbc2b712014-10-09 20:29:07584 ChunkedUploadDataStream upload_data_stream(0);
585 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:47586
587 request_.method = "POST";
588 request_.url = GURL("http://www.google.com/");
589 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07590 ASSERT_EQ(OK, request_.upload_data_stream->Init(
591 TestCompletionCallback().callback()));
[email protected]c9e49a02013-02-26 05:56:47592
[email protected]262eec82013-03-19 21:01:36593 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
594 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47595 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
596 callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47597
mmenkecbc2b712014-10-09 20:29:07598 upload_data_stream.AppendData(kUploadData, chunk_size, true);
rchb27683c2015-07-29 23:53:50599 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]c9e49a02013-02-26 05:56:47600
601 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20602 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47603
604 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20605 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45606 size_t spdy_response_headers_frame_length;
607 ProcessPacket(ConstructResponseHeadersPacket(
608 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:47609
rchb27683c2015-07-29 23:53:50610 // The headers have arrived, but they are delivered asynchronously
611 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
612 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36613 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47614 EXPECT_EQ(200, response_.headers->response_code());
615 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
616
617 // Send the response body.
618 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20619 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
620 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47621
622 // Since the body has already arrived, this should return immediately.
623 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
624 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
625 callback_.callback()));
626
627 EXPECT_TRUE(stream_->IsResponseBodyComplete());
628 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10629
630 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45631 // headers and payload.
632 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
633 strlen(kUploadData) * 2),
sclittle1edeeb22015-09-02 20:46:10634 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:45635 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
636 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10637 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:47638}
639
[email protected]16ba7742014-08-22 00:57:25640TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
641 SetRequest("POST", "/", DEFAULT_PRIORITY);
642 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:45643 size_t spdy_request_headers_frame_length;
644 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
645 &spdy_request_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25646 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
647 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
648 AddWrite(ConstructAckPacket(4, 3, 1));
649 Initialize();
650
mmenkecbc2b712014-10-09 20:29:07651 ChunkedUploadDataStream upload_data_stream(0);
652 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:25653
654 request_.method = "POST";
655 request_.url = GURL("http://www.google.com/");
656 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07657 ASSERT_EQ(OK, request_.upload_data_stream->Init(
658 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25659
660 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
661 net_log_, callback_.callback()));
662 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
663 callback_.callback()));
664
mmenkecbc2b712014-10-09 20:29:07665 upload_data_stream.AppendData(nullptr, 0, true);
rchb27683c2015-07-29 23:53:50666 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25667
668 ProcessPacket(ConstructAckPacket(1, 0, 0));
669
670 // Send the response headers (but not the body).
671 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45672 size_t spdy_response_headers_frame_length;
673 ProcessPacket(ConstructResponseHeadersPacket(
674 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25675
rchb27683c2015-07-29 23:53:50676 // The headers have arrived, but they are delivered asynchronously
677 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
678 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25679 ASSERT_TRUE(response_.headers.get());
680 EXPECT_EQ(200, response_.headers->response_code());
681 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
682
683 // Send the response body.
684 const char kResponseBody[] = "Hello world!";
685 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
686 kResponseBody));
687
rchb27683c2015-07-29 23:53:50688 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:25689 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
690 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
691 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:25692 EXPECT_TRUE(stream_->IsResponseBodyComplete());
693 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10694
695 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45696 // headers and payload.
697 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
698 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:10699 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:45700 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
701 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10702 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:25703}
704
705TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
706 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45707 size_t spdy_request_headers_frame_length;
708 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
709 &spdy_request_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25710 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
711 AddWrite(ConstructAckPacket(3, 3, 1));
712 Initialize();
713
mmenkecbc2b712014-10-09 20:29:07714 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:25715
716 request_.method = "POST";
717 request_.url = GURL("http://www.google.com/");
718 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07719 ASSERT_EQ(OK, request_.upload_data_stream->Init(
720 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25721
722 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
723 net_log_, callback_.callback()));
724 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
725 callback_.callback()));
726
mmenkecbc2b712014-10-09 20:29:07727 upload_data_stream.AppendData(nullptr, 0, true);
rchb27683c2015-07-29 23:53:50728 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25729
730 ProcessPacket(ConstructAckPacket(1, 0, 0));
731
732 // Send the response headers (but not the body).
733 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45734 size_t spdy_response_headers_frame_length;
735 ProcessPacket(ConstructResponseHeadersPacket(
736 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25737
rchb27683c2015-07-29 23:53:50738 // The headers have arrived, but they are delivered asynchronously
739 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
740 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25741 ASSERT_TRUE(response_.headers.get());
742 EXPECT_EQ(200, response_.headers->response_code());
743 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
744
745 // Send the response body.
746 const char kResponseBody[] = "Hello world!";
747 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
748 kResponseBody));
749
rchb27683c2015-07-29 23:53:50750 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:25751 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
752 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
753 callback_.callback()));
754
755 EXPECT_TRUE(stream_->IsResponseBodyComplete());
756 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10757
758 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45759 // headers and payload.
760 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
761 stream_->GetTotalSentBytes());
762 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
763 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10764 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:25765}
766
[email protected]1e960032013-12-20 19:00:20767TEST_P(QuicHttpStreamTest, DestroyedEarly) {
768 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45769 size_t spdy_request_headers_frame_length;
770 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
771 &spdy_request_headers_frame_length));
rtenneti4efd55dd2015-09-18 01:12:04772 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00773 use_closing_stream_ = true;
774 Initialize();
775
776 request_.method = "GET";
777 request_.url = GURL("http://www.google.com/");
778
[email protected]262eec82013-03-19 21:01:36779 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
780 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00781 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58782 callback_.callback()));
[email protected]63534512012-12-23 18:49:00783
784 // Ack the request.
[email protected]1e960032013-12-20 19:00:20785 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00786 EXPECT_EQ(ERR_IO_PENDING,
787 stream_->ReadResponseHeaders(callback_.callback()));
788
789 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20790 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00791 // In the course of processing this packet, the QuicHttpStream close itself.
sclittlec4dc1a32015-09-24 00:15:45792 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, nullptr));
[email protected]63534512012-12-23 18:49:00793
rchb27683c2015-07-29 23:53:50794 base::MessageLoop::current()->RunUntilIdle();
795
[email protected]63534512012-12-23 18:49:00796 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10797
798 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45799 // headers and payload.
800 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
801 stream_->GetTotalSentBytes());
802 // Zero since the stream is closed before processing the headers.
sclittle1edeeb22015-09-02 20:46:10803 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:00804}
805
[email protected]1e960032013-12-20 19:00:20806TEST_P(QuicHttpStreamTest, Priority) {
807 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:45808 size_t spdy_request_headers_frame_length;
809 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM,
810 &spdy_request_headers_frame_length));
rtenneti4efd55dd2015-09-18 01:12:04811 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58812 use_closing_stream_ = true;
813 Initialize();
814
815 request_.method = "GET";
816 request_.url = GURL("http://www.google.com/");
817
818 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
819 net_log_, callback_.callback()));
820
821 // Check that priority is highest.
822 QuicReliableClientStream* reliable_stream =
823 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
824 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14825 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58826 reliable_stream->EffectivePriority());
827
828 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
829 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58830
831 // Check that priority has now dropped back to MEDIUM.
832 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
833 reliable_stream->EffectivePriority()));
834
835 // Ack the request.
[email protected]1e960032013-12-20 19:00:20836 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58837 EXPECT_EQ(ERR_IO_PENDING,
838 stream_->ReadResponseHeaders(callback_.callback()));
839
840 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20841 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58842 // In the course of processing this packet, the QuicHttpStream close itself.
sclittlec4dc1a32015-09-24 00:15:45843 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, nullptr));
[email protected]24e5bc52013-09-18 15:36:58844
rchb27683c2015-07-29 23:53:50845 base::MessageLoop::current()->RunUntilIdle();
846
[email protected]24e5bc52013-09-18 15:36:58847 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10848
849 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45850 // headers and payload.
851 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
852 stream_->GetTotalSentBytes());
853 // Zero since the stream is closed before processing the headers.
sclittle1edeeb22015-09-02 20:46:10854 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:58855}
856
[email protected]e1cca9a2013-09-20 17:14:44857// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20858TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
859 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44860 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52861
[email protected]08da9adb2014-04-24 08:33:31862 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52863
[email protected]e1cca9a2013-09-20 17:14:44864 Initialize();
865
866 request_.method = "GET";
867 request_.url = GURL("http://www.google.com/");
868
869 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
870 net_log_, callback_.callback()));
871
872 // Check that priority is highest.
873 QuicReliableClientStream* reliable_stream =
874 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
875 DCHECK(reliable_stream);
876 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
877 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14878 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44879 reliable_stream->EffectivePriority());
880
rtennetibe635732014-10-02 22:51:42881 // Set Delegate to nullptr and make sure EffectivePriority returns highest
[email protected]e1cca9a2013-09-20 17:14:44882 // priority.
rtennetibe635732014-10-02 22:51:42883 reliable_stream->SetDelegate(nullptr);
[email protected]9f0dcd4e2014-01-16 15:58:14884 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44885 reliable_stream->EffectivePriority());
886 reliable_stream->SetDelegate(delegate);
sclittle1edeeb22015-09-02 20:46:10887
sclittle1edeeb22015-09-02 20:46:10888 EXPECT_EQ(0, stream_->GetTotalSentBytes());
889 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]e1cca9a2013-09-20 17:14:44890}
891
[email protected]f702d572012-12-04 15:56:20892} // namespace test
[email protected]f702d572012-12-04 15:56:20893} // namespace net