blob: 3fee89a46b85f3f5921e96b12f6bf0978f7050fb [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
rch675757b2016-07-29 16:40:115#include "net/quic/chromium/quic_http_stream.h"
[email protected]f702d572012-12-04 15:56:206
sclittle1edeeb22015-09-02 20:46:107#include <stdint.h>
8
danakjad1777e2016-04-16 00:56:429#include <memory>
bnc086b39e12016-06-24 13:05:2610#include <utility>
[email protected]f702d572012-12-04 15:56:2011
danakjad1777e2016-04-16 00:56:4212#include "base/memory/ptr_util.h"
fdoray92e35a72016-06-10 15:54:5513#include "base/run_loop.h"
xunjieli188bd402016-03-12 00:17:2514#include "base/strings/string_number_conversions.h"
gabf767595f2016-05-11 18:50:3515#include "base/threading/thread_task_runner_handle.h"
xunjieli84adaab2016-09-20 01:12:2816#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0717#include "net/base/chunked_upload_data_stream.h"
18#include "net/base/elements_upload_data_stream.h"
xunjieli84adaab2016-09-20 01:12:2819#include "net/base/load_timing_info.h"
20#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2021#include "net/base/net_errors.h"
22#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0623#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2024#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1525#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0026#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5427#include "net/log/test_net_log.h"
28#include "net/log/test_net_log_util.h"
rch675757b2016-07-29 16:40:1129#include "net/quic/chromium/crypto/proof_verifier_chromium.h"
rch223465c2016-12-08 21:17:2930#include "net/quic/chromium/mock_crypto_client_stream_factory.h"
rch675757b2016-07-29 16:40:1131#include "net/quic/chromium/quic_chromium_alarm_factory.h"
32#include "net/quic/chromium/quic_chromium_connection_helper.h"
33#include "net/quic/chromium/quic_chromium_packet_reader.h"
34#include "net/quic/chromium/quic_chromium_packet_writer.h"
rch223465c2016-12-08 21:17:2935#include "net/quic/chromium/quic_http_utils.h"
rchfaf834e2016-12-21 17:55:0236#include "net/quic/chromium/quic_server_info.h"
rch223465c2016-12-08 21:17:2937#include "net/quic/chromium/quic_test_packet_maker.h"
rch1e369362017-04-03 19:44:5138#include "net/quic/chromium/test_task_runner.h"
rchd4db7c152016-07-29 21:58:1239#include "net/quic/core/congestion_control/send_algorithm_interface.h"
40#include "net/quic/core/crypto/crypto_protocol.h"
41#include "net/quic/core/crypto/quic_decrypter.h"
42#include "net/quic/core/crypto/quic_encrypter.h"
rchd4db7c152016-07-29 21:58:1243#include "net/quic/core/quic_connection.h"
rchd4db7c152016-07-29 21:58:1244#include "net/quic/core/quic_write_blocked_list.h"
45#include "net/quic/core/spdy_utils.h"
Michael Warresed8ebd52017-12-22 22:42:0446#include "net/quic/core/tls_client_handshaker.h"
fayang19c30772017-03-09 15:06:1747#include "net/quic/platform/api/quic_string_piece.h"
rch1fe2eeb2015-10-26 14:45:5748#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]f702d572012-12-04 15:56:2049#include "net/quic/test_tools/mock_clock.h"
[email protected]9db443912013-02-25 05:27:0350#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3951#include "net/quic/test_tools/quic_connection_peer.h"
ckrasicbf2f59c2017-05-04 23:54:3652#include "net/quic/test_tools/quic_spdy_session_peer.h"
[email protected]f702d572012-12-04 15:56:2053#include "net/quic/test_tools/quic_test_utils.h"
tbansalca83c002016-04-28 20:56:2854#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2055#include "net/socket/socket_test_util.h"
bnc8f8f7d302017-04-24 18:08:0656#include "net/spdy/chromium/spdy_http_utils.h"
57#include "net/spdy/core/spdy_frame_builder.h"
58#include "net/spdy/core/spdy_framer.h"
59#include "net/spdy/core/spdy_protocol.h"
rch03b7a202016-02-05 00:54:2060#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0161#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4362#include "net/test/test_data_directory.h"
Ramin Halavati683bcaa92018-02-14 08:42:3963#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]f702d572012-12-04 15:56:2064#include "testing/gmock/include/gmock/gmock.h"
65#include "testing/gtest/include/gtest/gtest.h"
66
bnc614a92d32016-04-04 13:56:0767using std::string;
[email protected]f702d572012-12-04 15:56:2068using testing::_;
[email protected]06ff5152013-08-29 01:03:0569using testing::AnyNumber;
70using testing::Return;
[email protected]f702d572012-12-04 15:56:2071
72namespace net {
[email protected]f702d572012-12-04 15:56:2073namespace test {
[email protected]f702d572012-12-04 15:56:2074namespace {
75
[email protected]16ba7742014-08-22 00:57:2576const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2977const char kDefaultServerHostName[] = "www.example.org";
rchcd379012017-04-12 21:53:3278const uint16_t kDefaultServerPort = 443;
[email protected]f702d572012-12-04 15:56:2079
80class TestQuicConnection : public QuicConnection {
81 public:
Dan Zhangfefaf5b2017-12-11 17:06:2482 TestQuicConnection(const ParsedQuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4383 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2084 IPEndPoint address,
rch12fef552016-01-15 16:26:3185 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0786 QuicChromiumAlarmFactory* alarm_factory,
jdorfman90d185f32016-01-15 13:22:4787 QuicPacketWriter* writer)
[email protected]66cd2d62014-08-01 18:42:3988 : QuicConnection(connection_id,
fayang91ca2012016-11-22 07:42:4689 QuicSocketAddress(QuicSocketAddressImpl(address)),
[email protected]66cd2d62014-08-01 18:42:3990 helper,
rch16c74d1d2016-04-22 06:14:0791 alarm_factory,
jdorfman90d185f32016-01-15 13:22:4792 writer,
rtenneti6f48aa92015-03-16 02:18:4893 true /* owns_writer */,
94 Perspective::IS_CLIENT,
rtenneti6f48aa92015-03-16 02:18:4895 versions) {}
[email protected]f702d572012-12-04 15:56:2096
[email protected]fee17f72013-02-03 07:47:4197 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
fayang754ab6572017-01-18 20:39:0498 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2099 }
100};
101
maksim.sisov84e20c92016-06-23 08:49:34102// UploadDataStream that always returns errors on data read.
103class ReadErrorUploadDataStream : public UploadDataStream {
104 public:
105 enum class FailureMode { SYNC, ASYNC };
106
107 explicit ReadErrorUploadDataStream(FailureMode mode)
108 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {}
109 ~ReadErrorUploadDataStream() override {}
110
111 private:
112 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
113
114 // UploadDataStream implementation:
tfarina42834112016-09-22 13:38:20115 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34116
117 int ReadInternal(IOBuffer* buf, int buf_len) override {
118 if (async_ == FailureMode::ASYNC) {
119 base::ThreadTaskRunnerHandle::Get()->PostTask(
120 FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead,
121 weak_factory_.GetWeakPtr()));
122 return ERR_IO_PENDING;
123 }
124 return ERR_FAILED;
125 }
126
127 void ResetInternal() override {}
128
129 const FailureMode async_;
130
131 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_;
132
133 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
134};
135
xunjieli8dff50b2016-07-22 14:19:06136// A Callback that deletes the QuicHttpStream.
137class DeleteStreamCallback : public TestCompletionCallbackBase {
138 public:
139 DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
140 : stream_(std::move(stream)),
141 callback_(base::Bind(&DeleteStreamCallback::DeleteStream,
142 base::Unretained(this))) {}
143
144 const CompletionCallback& callback() const { return callback_; }
145
146 private:
147 void DeleteStream(int result) {
148 stream_.reset();
149 SetResult(result);
150 }
151
152 std::unique_ptr<QuicHttpStream> stream_;
153 CompletionCallback callback_;
154};
155
[email protected]f702d572012-12-04 15:56:20156} // namespace
157
[email protected]24e5bc52013-09-18 15:36:58158class QuicHttpStreamPeer {
159 public:
rch08e198572017-05-09 16:56:55160 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58161 QuicHttpStream* stream) {
rch08e198572017-05-09 16:56:55162 return stream->stream_.get();
[email protected]24e5bc52013-09-18 15:36:58163 }
164};
165
Michael Warres74ee3ce2017-10-09 15:26:37166class QuicHttpStreamTest
Yixin Wang079ad542018-01-11 04:06:05167 : public ::testing::TestWithParam<std::tuple<QuicTransportVersion, bool>> {
rchfb47f712017-05-21 03:24:00168 public:
169 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
170
[email protected]f702d572012-12-04 15:56:20171 protected:
[email protected]1e960032013-12-20 19:00:20172 static const bool kFin = true;
173 static const bool kIncludeVersion = true;
174 static const bool kIncludeCongestionFeedback = true;
175
[email protected]f702d572012-12-04 15:56:20176 // Holds a packet to be written to the wire, and the IO mode that should
177 // be used by the mock socket when performing the write.
178 struct PacketToWrite {
jokulikf2bd55c52016-03-24 22:35:30179 PacketToWrite(IoMode mode, QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02180 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03181 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20182 IoMode mode;
jokulikf2bd55c52016-03-24 22:35:30183 QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03184 int rv;
[email protected]f702d572012-12-04 15:56:20185 };
186
187 QuicHttpStreamTest()
Yixin Wang079ad542018-01-11 04:06:05188 : version_(std::get<0>(GetParam())),
189 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
190 crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
Michael Warresed8ebd52017-12-22 22:42:04191 TlsClientHandshaker::CreateSslCtx()),
[email protected]f702d572012-12-04 15:56:20192 read_buffer_(new IOBufferWithSize(4096)),
ckrasicbf2f59c2017-05-04 23:54:36193 promise_id_(GetNthServerInitiatedStreamId(0)),
194 stream_id_(GetNthClientInitiatedStreamId(0)),
ckrasic3865ee0f2016-02-29 22:04:56195 connection_id_(2),
Yixin Wang079ad542018-01-11 04:06:05196 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58197 connection_id_,
198 &clock_,
199 kDefaultServerHostName,
Yixin Wang079ad542018-01-11 04:06:05200 Perspective::IS_CLIENT,
201 client_headers_include_h2_stream_dependency_),
202 server_maker_(version_,
zhongyi5dbfdd42017-06-20 05:22:15203 connection_id_,
alyssar2adf3ac2016-05-03 17:12:58204 &clock_,
205 kDefaultServerHostName,
Yixin Wang079ad542018-01-11 04:06:05206 Perspective::IS_SERVER,
207 false),
ckrasic3865ee0f2016-02-29 22:04:56208 random_generator_(0),
209 response_offset_(0) {
martijn21968ea2016-02-24 18:46:20210 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20211 peer_addr_ = IPEndPoint(ip, 443);
212 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43213 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
Ramin Halavati683bcaa92018-02-14 08:42:39214 request_.traffic_annotation =
215 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f702d572012-12-04 15:56:20216 }
217
218 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19219 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20220 for (size_t i = 0; i < writes_.size(); i++) {
221 delete writes_[i].packet;
222 }
223 }
224
225 // Adds a packet to the list of expected writes.
danakjad1777e2016-04-16 00:56:42226 void AddWrite(std::unique_ptr<QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20227 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20228 }
229
rtenneti15656ae2016-01-23 03:05:03230 void AddWrite(IoMode mode, int rv) {
231 writes_.push_back(PacketToWrite(mode, rv));
232 }
233
[email protected]f702d572012-12-04 15:56:20234 // Returns the packet to be written at position |pos|.
jokulikf2bd55c52016-03-24 22:35:30235 QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20236
237 bool AtEof() {
rch37de576c2015-05-17 20:28:17238 return socket_data_->AllReadDataConsumed() &&
239 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20240 }
241
danakjad1777e2016-04-16 00:56:42242 void ProcessPacket(std::unique_ptr<QuicReceivedPacket> packet) {
fayang91ca2012016-11-22 07:42:46243 connection_->ProcessUdpPacket(
244 QuicSocketAddress(QuicSocketAddressImpl(self_addr_)),
245 QuicSocketAddress(QuicSocketAddressImpl(peer_addr_)), *packet);
[email protected]f702d572012-12-04 15:56:20246 }
247
248 // Configures the test fixture to use the list of expected writes.
249 void Initialize() {
250 mock_writes_.reset(new MockWrite[writes_.size()]);
251 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03252 if (writes_[i].packet == nullptr) {
253 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
254 } else {
255 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
256 writes_[i].packet->length());
257 }
bnc614a92d32016-04-04 13:56:07258 }
[email protected]f702d572012-12-04 15:56:20259
rtennetibe635732014-10-02 22:51:42260 socket_data_.reset(new StaticSocketDataProvider(
261 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20262
danakjad1777e2016-04-16 00:56:42263 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36264 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32265 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20266 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41267 send_algorithm_ = new MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57268 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
269 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
rjshaded5ced072015-12-18 19:26:02270 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09271 .Times(testing::AtLeast(1));
rtenneti44f4a2e2015-08-07 14:00:07272 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
273 .WillRepeatedly(Return(kMaxPacketSize));
jokulik0e0a00c32016-06-13 21:51:58274 EXPECT_CALL(*send_algorithm_, PacingRate(_))
rtenneti44f4a2e2015-08-07 14:00:07275 .WillRepeatedly(Return(QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37276 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07277 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
278 .WillRepeatedly(Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40279 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch08cae032017-03-29 00:59:15280 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
rch0d5bcf62017-05-24 22:48:45281 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
282 .Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07283 helper_.reset(
284 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
285 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
286
Michael Warres74ee3ce2017-10-09 15:26:37287 connection_ = new TestQuicConnection(
Dan Zhangfefaf5b2017-12-11 17:06:24288 SupportedVersions(
Yixin Wang079ad542018-01-11 04:06:05289 net::ParsedQuicVersion(net::PROTOCOL_QUIC_CRYPTO, version_)),
Dan Zhangfefaf5b2017-12-11 17:06:24290 connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
Ryan Hamilton9edcf1a2017-11-22 05:55:17291 new QuicChromiumPacketWriter(
292 socket.get(), base::ThreadTaskRunnerHandle::Get().get()));
[email protected]f702d572012-12-04 15:56:20293 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41294 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20295
296 // Load a certificate that is valid for *.example.org
297 scoped_refptr<X509Certificate> test_cert(
298 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
299 EXPECT_TRUE(test_cert.get());
300
301 verify_details_.cert_verify_result.verified_cert = test_cert;
302 verify_details_.cert_verify_result.is_issued_by_known_root = true;
303 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
304
xunjieli84adaab2016-09-20 01:12:28305 base::TimeTicks dns_end = base::TimeTicks::Now();
306 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16307 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36308 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28309 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
bnc614a92d32016-04-04 13:56:07310 &transport_security_state_,
danakjad1777e2016-04-16 00:56:42311 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
bncb07c05532015-05-14 19:07:20312 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
rch1fe2eeb2015-10-26 14:45:57313 PRIVACY_MODE_DISABLED),
Zhongyi Shi22e91af2017-10-21 00:53:57314 /*require_confirmation=*/false, /*migrate_session_early*/ false,
Zhongyi Shi5f587cc2017-11-21 23:24:17315 /*migrate_session_on_network_change*/ false,
Zhongyi Shif4683a32017-12-01 00:03:28316 /*migrate_session_early_v2*/ false,
Zhongyi Shi5f587cc2017-11-21 23:24:17317 /*migrate_session_on_network_change_v2*/ false,
Zhongyi Shi73f23ca872017-12-13 18:37:13318 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shi8b1e43f2017-12-13 20:46:30319 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17320 kQuicYieldAfterPacketsRead,
rtenneti1cd3b162015-09-29 02:58:28321 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05322 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
323 DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN", dns_start,
324 dns_end, &push_promise_index_, nullptr,
xunjieli84adaab2016-09-20 01:12:28325 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54326 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52327 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37328 TestCompletionCallback callback;
rchf0b18c8a2017-05-05 19:31:57329
rch433bf5f2017-02-14 04:10:47330 session_->CryptoConnect(callback.callback());
Ryan Hamilton6c2a2a82017-12-15 02:06:28331 stream_ = std::make_unique<QuicHttpStream>(
332 session_->CreateHandle(HostPortPair("www.example.org", 443)));
333 promised_stream_ = std::make_unique<QuicHttpStream>(
334 session_->CreateHandle(HostPortPair("www.example.org", 443)));
ckrasic3865ee0f2016-02-29 22:04:56335 push_promise_[":path"] = "/bar";
336 push_promise_[":authority"] = "www.example.org";
337 push_promise_[":version"] = "HTTP/1.1";
338 push_promise_[":method"] = "GET";
339 push_promise_[":scheme"] = "https";
340
341 promised_response_[":status"] = "200 OK";
342 promised_response_[":version"] = "HTTP/1.1";
343 promised_response_["content-type"] = "text/plain";
344
Yixin Wang81c11182018-02-05 20:09:57345 promise_url_ = SpdyUtils::GetPromisedUrlFromHeaderBlock(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36346 }
347
bnc614a92d32016-04-04 13:56:07348 void SetRequest(const string& method,
349 const string& path,
[email protected]1e960032013-12-20 19:00:20350 RequestPriority priority) {
rchcd379012017-04-12 21:53:32351 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
[email protected]6cca996b2013-01-25 07:43:36352 }
353
bnc614a92d32016-04-04 13:56:07354 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58355 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03356 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36357 }
[email protected]f702d572012-12-04 15:56:20358
danakjad1777e2016-04-16 00:56:42359 std::unique_ptr<QuicReceivedPacket> InnerConstructDataPacket(
ckrasic3865ee0f2016-02-29 22:04:56360 QuicPacketNumber packet_number,
361 QuicStreamId stream_id,
362 bool should_include_version,
363 bool fin,
364 QuicStreamOffset offset,
fayang19c30772017-03-09 15:06:17365 QuicStringPiece data,
alyssar2adf3ac2016-05-03 17:12:58366 QuicTestPacketMaker* maker) {
367 return maker->MakeDataPacket(packet_number, stream_id,
ckrasic3865ee0f2016-02-29 22:04:56368 should_include_version, fin, offset, data);
369 }
370
alyssar2adf3ac2016-05-03 17:12:58371 std::unique_ptr<QuicReceivedPacket> ConstructClientDataPacket(
rtennetia004d332015-08-28 06:44:57372 QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05373 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20374 bool fin,
375 QuicStreamOffset offset,
fayang19c30772017-03-09 15:06:17376 QuicStringPiece data) {
ckrasic3865ee0f2016-02-29 22:04:56377 return InnerConstructDataPacket(packet_number, stream_id_,
alyssar2adf3ac2016-05-03 17:12:58378 should_include_version, fin, offset, data,
379 &client_maker_);
380 }
381
382 std::unique_ptr<QuicReceivedPacket> ConstructServerDataPacket(
383 QuicPacketNumber packet_number,
384 bool should_include_version,
385 bool fin,
386 QuicStreamOffset offset,
fayang19c30772017-03-09 15:06:17387 QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58388 return InnerConstructDataPacket(packet_number, stream_id_,
389 should_include_version, fin, offset, data,
390 &server_maker_);
ckrasic3865ee0f2016-02-29 22:04:56391 }
392
danakjad1777e2016-04-16 00:56:42393 std::unique_ptr<QuicReceivedPacket> InnerConstructRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56394 QuicPacketNumber packet_number,
395 QuicStreamId stream_id,
396 bool should_include_version,
397 bool fin,
398 RequestPriority request_priority,
xunjieli100937eb52016-09-15 20:09:37399 size_t* spdy_headers_frame_length,
400 QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48401 return InnerConstructRequestHeadersPacket(
402 packet_number, stream_id, should_include_version, fin, request_priority,
403 0, spdy_headers_frame_length, offset);
404 }
405
406 std::unique_ptr<QuicReceivedPacket> InnerConstructRequestHeadersPacket(
407 QuicPacketNumber packet_number,
408 QuicStreamId stream_id,
409 bool should_include_version,
410 bool fin,
411 RequestPriority request_priority,
412 QuicStreamId parent_stream_id,
413 size_t* spdy_headers_frame_length,
414 QuicStreamOffset* offset) {
ckrasic3865ee0f2016-02-29 22:04:56415 SpdyPriority priority =
416 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58417 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56418 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48419 std::move(request_headers_), parent_stream_id,
420 spdy_headers_frame_length, offset);
[email protected]f702d572012-12-04 15:56:20421 }
422
danakjad1777e2016-04-16 00:56:42423 std::unique_ptr<QuicReceivedPacket> ConstructRequestHeadersPacket(
rtennetia004d332015-08-28 06:44:57424 QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05425 bool fin,
sclittlec4dc1a32015-09-24 00:15:45426 RequestPriority request_priority,
427 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56428 return InnerConstructRequestHeadersPacket(
429 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
xunjieli100937eb52016-09-15 20:09:37430 spdy_headers_frame_length, nullptr);
ckrasic3865ee0f2016-02-29 22:04:56431 }
432
danakjad1777e2016-04-16 00:56:42433 std::unique_ptr<QuicReceivedPacket> InnerConstructResponseHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56434 QuicPacketNumber packet_number,
435 QuicStreamId stream_id,
436 bool fin,
437 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58438 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26439 packet_number, stream_id, !kIncludeVersion, fin,
440 std::move(response_headers_), spdy_headers_frame_length,
441 &response_offset_);
[email protected]1e960032013-12-20 19:00:20442 }
443
danakjad1777e2016-04-16 00:56:42444 std::unique_ptr<QuicReceivedPacket> ConstructResponseHeadersPacket(
rtennetia004d332015-08-28 06:44:57445 QuicPacketNumber packet_number,
sclittlec4dc1a32015-09-24 00:15:45446 bool fin,
447 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56448 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
449 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20450 }
451
danakjad1777e2016-04-16 00:56:42452 std::unique_ptr<QuicReceivedPacket> ConstructResponseHeadersPacketWithOffset(
xunjieli34291fe12016-03-02 13:58:38453 QuicPacketNumber packet_number,
454 bool fin,
455 size_t* spdy_headers_frame_length,
456 QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58457 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26458 packet_number, stream_id_, !kIncludeVersion, fin,
459 std::move(response_headers_), spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38460 }
461
danakjad1777e2016-04-16 00:56:42462 std::unique_ptr<QuicReceivedPacket> ConstructResponseTrailersPacket(
xunjieli34291fe12016-03-02 13:58:38463 QuicPacketNumber packet_number,
464 bool fin,
bnc086b39e12016-06-24 13:05:26465 SpdyHeaderBlock trailers,
xunjieli34291fe12016-03-02 13:58:38466 size_t* spdy_headers_frame_length,
467 QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58468 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26469 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
alyssar2adf3ac2016-05-03 17:12:58470 spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38471 }
472
alyssar2adf3ac2016-05-03 17:12:58473 std::unique_ptr<QuicReceivedPacket> ConstructClientRstStreamPacket(
rtennetia004d332015-08-28 06:44:57474 QuicPacketNumber packet_number) {
alyssara72f5352016-10-20 12:45:16475 return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
476 QUIC_RST_ACKNOWLEDGEMENT);
[email protected]06ff5152013-08-29 01:03:05477 }
478
alyssar2adf3ac2016-05-03 17:12:58479 std::unique_ptr<QuicReceivedPacket> ConstructClientRstStreamCancelledPacket(
rtennetia004d332015-08-28 06:44:57480 QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58481 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
482 stream_id_, QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53483 }
484
alyssar2adf3ac2016-05-03 17:12:58485 std::unique_ptr<QuicReceivedPacket>
486 ConstructClientRstStreamVaryMismatchPacket(QuicPacketNumber packet_number) {
487 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
488 promise_id_, QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56489 }
490
danakjad1777e2016-04-16 00:56:42491 std::unique_ptr<QuicReceivedPacket> ConstructAckAndRstStreamPacket(
xunjieli34291fe12016-03-02 13:58:38492 QuicPacketNumber packet_number,
493 QuicPacketNumber largest_received,
wangyix6444ffe2017-04-25 17:49:49494 QuicPacketNumber smallest_received,
495 QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58496 return client_maker_.MakeAckAndRstPacket(
xunjieli34291fe12016-03-02 13:58:38497 packet_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
wangyix6444ffe2017-04-25 17:49:49498 largest_received, smallest_received, least_unacked,
xunjieli34291fe12016-03-02 13:58:38499 !kIncludeCongestionFeedback);
500 }
501
maksim.sisov84e20c92016-06-23 08:49:34502 std::unique_ptr<QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
503 QuicPacketNumber packet_number,
504 bool include_version) {
505 return client_maker_.MakeRstPacket(packet_number, include_version,
506 stream_id_,
507 QUIC_ERROR_PROCESSING_STREAM);
508 }
509
danakjad1777e2016-04-16 00:56:42510 std::unique_ptr<QuicReceivedPacket> ConstructAckAndRstStreamPacket(
rtennetia004d332015-08-28 06:44:57511 QuicPacketNumber packet_number) {
xunjieli34291fe12016-03-02 13:58:38512 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 1);
[email protected]c5e1aca2014-01-30 04:03:04513 }
514
alyssar2adf3ac2016-05-03 17:12:58515 std::unique_ptr<QuicReceivedPacket> ConstructClientAckPacket(
rtennetia004d332015-08-28 06:44:57516 QuicPacketNumber packet_number,
517 QuicPacketNumber largest_received,
wangyix6444ffe2017-04-25 17:49:49518 QuicPacketNumber smallest_received,
rtennetia004d332015-08-28 06:44:57519 QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58520 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49521 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58522 !kIncludeCongestionFeedback);
523 }
524
525 std::unique_ptr<QuicReceivedPacket> ConstructServerAckPacket(
526 QuicPacketNumber packet_number,
527 QuicPacketNumber largest_received,
wangyix6444ffe2017-04-25 17:49:49528 QuicPacketNumber smallest_received,
alyssar2adf3ac2016-05-03 17:12:58529 QuicPacketNumber least_unacked) {
530 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49531 smallest_received, least_unacked,
alyssar2adf3ac2016-05-03 17:12:58532 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00533 }
534
rch5cb522462017-04-25 20:18:36535 std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket(
fayang3bcb8b502016-12-07 21:44:37536 QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36537 return client_maker_.MakeInitialSettingsPacket(1, offset);
fayang3bcb8b502016-12-07 21:44:37538 }
539
ckrasic3865ee0f2016-02-29 22:04:56540 void ReceivePromise(QuicStreamId id) {
ckrasic32b17dcd2016-10-31 06:15:35541 auto headers = AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55542 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56543 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35544 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
545 headers);
ckrasic3865ee0f2016-02-29 22:04:56546 }
547
xunjieli84adaab2016-09-20 01:12:28548 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37549 bool session_reused) {
550 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28551 if (session_reused) {
552 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
553 } else {
554 ExpectConnectTimingHasTimes(
555 load_timing_info.connect_timing,
556 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
557 }
558 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37559 }
560
ckrasicbf2f59c2017-05-04 23:54:36561 QuicStreamId GetNthClientInitiatedStreamId(int n) {
Yixin Wang079ad542018-01-11 04:06:05562 return test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36563 }
564
565 QuicStreamId GetNthServerInitiatedStreamId(int n) {
Yixin Wang079ad542018-01-11 04:06:05566 return test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36567 }
568
Yixin Wang079ad542018-01-11 04:06:05569 const QuicTransportVersion version_;
570 const bool client_headers_include_h2_stream_dependency_;
571
xunjieli5fafe142016-03-23 23:32:54572 BoundTestNetLog net_log_;
[email protected]fee17f72013-02-03 07:47:41573 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20574 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42575 std::unique_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20576 MockClock clock_;
577 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42578 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07579 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
ckrasica7fd1242016-05-14 20:36:01580 testing::StrictMock<MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12581 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42582 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15583 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42584 std::unique_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01585 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20586 TestCompletionCallback callback_;
587 HttpRequestInfo request_;
588 HttpRequestHeaders headers_;
589 HttpResponseInfo response_;
590 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20591 SpdyHeaderBlock request_headers_;
592 SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07593 string request_data_;
594 string response_data_;
ckrasic244375a32016-02-04 21:21:22595 QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20596
ckrasic3865ee0f2016-02-29 22:04:56597 // For server push testing
danakjad1777e2016-04-16 00:56:42598 std::unique_ptr<QuicHttpStream> promised_stream_;
ckrasic3865ee0f2016-02-29 22:04:56599 SpdyHeaderBlock push_promise_;
600 SpdyHeaderBlock promised_response_;
601 const QuicStreamId promise_id_;
602 string promise_url_;
ckrasic3865ee0f2016-02-29 22:04:56603 const QuicStreamId stream_id_;
604
[email protected]3aa9ca72014-02-27 19:39:43605 const QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58606 QuicTestPacketMaker client_maker_;
607 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20608 IPEndPoint self_addr_;
609 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58610 MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20611 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05612 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42613 std::unique_ptr<StaticSocketDataProvider> socket_data_;
[email protected]f702d572012-12-04 15:56:20614 std::vector<PacketToWrite> writes_;
ckrasic3865ee0f2016-02-29 22:04:56615 QuicStreamOffset response_offset_;
[email protected]f702d572012-12-04 15:56:20616};
617
Yixin Wang079ad542018-01-11 04:06:05618INSTANTIATE_TEST_CASE_P(
619 VersionIncludeStreamDependencySequnece,
620 QuicHttpStreamTest,
621 ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
622 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20623
624TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44625 Initialize();
rtennetibe635732014-10-02 22:51:42626 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20627}
628
mmenkebd84c392015-09-02 14:12:34629TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44630 Initialize();
mmenkebd84c392015-09-02 14:12:34631 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20632}
633
jri231c2972016-03-08 19:50:11634TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
635 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
636 Initialize();
xunjieli5fafe142016-03-23 23:32:54637 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27638 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54639 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55640 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11641 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
642 EXPECT_FALSE(client_stream->can_migrate());
643}
644
[email protected]1e960032013-12-20 19:00:20645TEST_P(QuicHttpStreamTest, GetRequest) {
646 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45647 size_t spdy_request_header_frame_length;
fayang3bcb8b502016-12-07 21:44:37648 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36649 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37650 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36651 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
652 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
653 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37654
[email protected]f702d572012-12-04 15:56:20655 Initialize();
656
657 request_.method = "GET";
rchcd379012017-04-12 21:53:32658 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20659
xunjieli100937eb52016-09-15 20:09:37660 // Make sure getting load timing from the stream early does not crash.
661 LoadTimingInfo load_timing_info;
662 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
663
xunjieli5fafe142016-03-23 23:32:54664 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27665 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54666 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02667 EXPECT_EQ(OK,
668 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20669
670 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49671 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:20672
robpercival214763f2016-07-01 23:27:01673 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
674 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20675
bnc614a92d32016-04-04 13:56:07676 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45677 size_t spdy_response_header_frame_length;
678 ProcessPacket(ConstructResponseHeadersPacket(
679 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20680
681 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01682 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36683 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20684 EXPECT_EQ(404, response_.headers->response_code());
685 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53686 EXPECT_FALSE(response_.response_time.is_null());
687 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20688
689 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02690 EXPECT_EQ(0,
691 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
692 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20693 EXPECT_TRUE(stream_->IsResponseBodyComplete());
694 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10695
xunjieli100937eb52016-09-15 20:09:37696 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28697 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37698
sclittle1edeeb22015-09-02 20:46:10699 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45700 // headers and payload.
701 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
702 stream_->GetTotalSentBytes());
703 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
704 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20705}
706
xunjieli100937eb52016-09-15 20:09:37707TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
708 SetRequest("GET", "/", DEFAULT_PRIORITY);
709 size_t spdy_request_header_frame_length;
710
711 QuicStreamOffset offset = 0;
rch5cb522462017-04-25 20:18:36712 AddWrite(ConstructInitialSettingsPacket(&offset));
xunjieli100937eb52016-09-15 20:09:37713 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36714 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
715 DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset));
xunjieli100937eb52016-09-15 20:09:37716
717 // SetRequest() again for second request as |request_headers_| was moved.
718 SetRequest("GET", "/", DEFAULT_PRIORITY);
719 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36720 3, GetNthClientInitiatedStreamId(1), kIncludeVersion, kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48721 DEFAULT_PRIORITY, GetNthClientInitiatedStreamId(0),
722 &spdy_request_header_frame_length, &offset));
wangyix6444ffe2017-04-25 17:49:49723 AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37724
725 Initialize();
726
727 request_.method = "GET";
rchcd379012017-04-12 21:53:32728 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37729 // Start first request.
730 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27731 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37732 net_log_.bound(), callback_.callback()));
733 EXPECT_EQ(OK,
734 stream_->SendRequest(headers_, &response_, callback_.callback()));
735
736 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28737 QuicHttpStream stream2(
738 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37739 TestCompletionCallback callback2;
740 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27741 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37742 net_log_.bound(), callback2.callback()));
743 EXPECT_EQ(OK,
744 stream2.SendRequest(headers_, &response_, callback2.callback()));
745
746 // Ack both requests.
wangyix6444ffe2017-04-25 17:49:49747 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli100937eb52016-09-15 20:09:37748
749 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
750 IsError(ERR_IO_PENDING));
751 size_t spdy_response_header_frame_length;
752 SetResponse("200 OK", string());
753 ProcessPacket(InnerConstructResponseHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36754 2, GetNthClientInitiatedStreamId(0), kFin,
755 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37756
757 // Now that the headers have been processed, the callback will return.
758 EXPECT_THAT(callback_.WaitForResult(), IsOk());
759 EXPECT_EQ(200, response_.headers->response_code());
760
761 // There is no body, so this should return immediately.
762 EXPECT_EQ(0,
763 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
764 callback_.callback()));
765 EXPECT_TRUE(stream_->IsResponseBodyComplete());
766
767 LoadTimingInfo load_timing_info;
768 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28769 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37770
771 // SetResponse() again for second request as |response_headers_| was moved.
772 SetResponse("200 OK", string());
773 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
774 IsError(ERR_IO_PENDING));
775
776 ProcessPacket(InnerConstructResponseHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36777 3, GetNthClientInitiatedStreamId(1), kFin,
778 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37779
780 EXPECT_THAT(callback2.WaitForResult(), IsOk());
781
782 // There is no body, so this should return immediately.
783 EXPECT_EQ(0,
784 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
785 callback2.callback()));
786 EXPECT_TRUE(stream2.IsResponseBodyComplete());
787
788 LoadTimingInfo load_timing_info2;
789 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28790 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37791}
792
xunjieli34291fe12016-03-02 13:58:38793// QuicHttpStream does not currently support trailers. It should ignore
794// trailers upon receiving them.
795TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
796 SetRequest("GET", "/", DEFAULT_PRIORITY);
797 size_t spdy_request_header_frame_length;
fayang3bcb8b502016-12-07 21:44:37798 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36799 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37800 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36801 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
802 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
803 &header_stream_offset));
wangyix6444ffe2017-04-25 17:49:49804 AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38805
806 Initialize();
807
808 request_.method = "GET";
rchcd379012017-04-12 21:53:32809 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38810
xunjieli5fafe142016-03-23 23:32:54811 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27812 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54813 net_log_.bound(), callback_.callback()));
814
xunjieli34291fe12016-03-02 13:58:38815 EXPECT_EQ(OK,
816 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38817 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49818 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli34291fe12016-03-02 13:58:38819
robpercival214763f2016-07-01 23:27:01820 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
821 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38822
bnc614a92d32016-04-04 13:56:07823 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38824
825 // Send the response headers.
826 size_t spdy_response_header_frame_length;
827 QuicStreamOffset offset = 0;
828 ProcessPacket(ConstructResponseHeadersPacketWithOffset(
829 2, !kFin, &spdy_response_header_frame_length, &offset));
830 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01831 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38832 ASSERT_TRUE(response_.headers.get());
833 EXPECT_EQ(200, response_.headers->response_code());
834 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
835 EXPECT_FALSE(response_.response_time.is_null());
836 EXPECT_FALSE(response_.request_time.is_null());
837
838 // Send the response body.
839 const char kResponseBody[] = "Hello world!";
840 ProcessPacket(
alyssar2adf3ac2016-05-03 17:12:58841 ConstructServerDataPacket(3, false, !kFin, /*offset=*/0, kResponseBody));
xunjieli34291fe12016-03-02 13:58:38842 SpdyHeaderBlock trailers;
843 size_t spdy_trailers_frame_length;
844 trailers["foo"] = "bar";
xunjieli188bd402016-03-12 00:17:25845 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
xunjieli34291fe12016-03-02 13:58:38846 ProcessPacket(ConstructResponseTrailersPacket(
bnc086b39e12016-06-24 13:05:26847 4, kFin, std::move(trailers), &spdy_trailers_frame_length, &offset));
xunjieli34291fe12016-03-02 13:58:38848
849 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55850 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38851
852 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
853 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
854 callback_.callback()));
855 EXPECT_TRUE(stream_->IsResponseBodyComplete());
856
857 EXPECT_EQ(OK,
858 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
859 callback_.callback()));
860
861 EXPECT_TRUE(stream_->IsResponseBodyComplete());
862 EXPECT_TRUE(AtEof());
863
864 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
865 // headers and payload.
866 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
867 stream_->GetTotalSentBytes());
868 EXPECT_EQ(
869 static_cast<int64_t>(spdy_response_header_frame_length +
870 strlen(kResponseBody) + +spdy_trailers_frame_length),
871 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54872 // Check that NetLog was filled as expected.
873 TestNetLogEntry::List entries;
874 net_log_.GetEntries(&entries);
875 size_t pos = ExpectLogContainsSomewhere(
876 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00877 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
878 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54879 pos = ExpectLogContainsSomewhere(
880 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00881 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
882 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54883 ExpectLogContainsSomewhere(
884 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00885 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
886 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38887}
888
[email protected]3e7dca62013-09-10 16:14:23889// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20890TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
891 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45892 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:37893 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36894 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37895 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36896 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
897 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
898 &header_stream_offset));
[email protected]3e7dca62013-09-10 16:14:23899 Initialize();
900
901 request_.method = "GET";
rchcd379012017-04-12 21:53:32902 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:23903
xunjieli5fafe142016-03-23 23:32:54904 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27905 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54906 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02907 EXPECT_EQ(OK,
908 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23909
910 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49911 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23912
robpercival214763f2016-07-01 23:27:01913 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
914 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:23915
bnc086b39e12016-06-24 13:05:26916 response_headers_[":status"] = "200 OK";
917 response_headers_[":version"] = "HTTP/1.1";
918 response_headers_["content-type"] = "text/plain";
919 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23920
sclittlec4dc1a32015-09-24 00:15:45921 size_t spdy_response_headers_frame_length;
922 ProcessPacket(ConstructResponseHeadersPacket(
923 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23924
925 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01926 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:23927 ASSERT_TRUE(response_.headers.get());
928 EXPECT_EQ(200, response_.headers->response_code());
929 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
930
931 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02932 EXPECT_EQ(0,
933 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
934 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23935 EXPECT_TRUE(stream_->IsResponseBodyComplete());
936 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10937
938 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45939 // headers and payload.
940 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
941 stream_->GetTotalSentBytes());
942 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
943 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:23944}
945
rchf9f103cbc2014-08-30 05:28:04946// Regression test for http://crbug.com/409101
947TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
948 SetRequest("GET", "/", DEFAULT_PRIORITY);
949 Initialize();
950
951 request_.method = "GET";
rchcd379012017-04-12 21:53:32952 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:04953
xunjieli5fafe142016-03-23 23:32:54954 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27955 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54956 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:04957
jri78ec06a2016-03-31 18:19:40958 session_->connection()->CloseConnection(
959 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:04960
961 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:02962 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10963
964 EXPECT_EQ(0, stream_->GetTotalSentBytes());
965 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:04966}
967
rch03b7a202016-02-05 00:54:20968// Regression test for http://crbug.com/584441
969TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
970 SetRequest("GET", "/", DEFAULT_PRIORITY);
971 Initialize();
972
973 request_.method = "GET";
rchcd379012017-04-12 21:53:32974 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:20975
xunjieli5fafe142016-03-23 23:32:54976 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27977 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54978 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:20979
980 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:47981 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:20982 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:47983 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:20984
jri78ec06a2016-03-31 18:19:40985 session_->connection()->CloseConnection(
986 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:20987
rch11565e02016-02-09 20:13:47988 SSLInfo ssl_info2;
989 stream_->GetSSLInfo(&ssl_info2);
990 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:20991}
992
rchcd379012017-04-12 21:53:32993TEST_P(QuicHttpStreamTest, GetAlternativeService) {
994 SetRequest("GET", "/", DEFAULT_PRIORITY);
995 Initialize();
996
997 request_.method = "GET";
998 request_.url = GURL("https://www.example.org/");
999
1000 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271001 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321002 net_log_.bound(), callback_.callback()));
1003
1004 AlternativeService alternative_service;
1005 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1006 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1007 alternative_service);
1008
1009 session_->connection()->CloseConnection(
1010 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
1011
1012 AlternativeService alternative_service2;
1013 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1014 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1015 alternative_service2);
1016}
1017
zhongyica364fbb2015-12-12 03:39:121018TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1019 SetRequest("GET", "/", DEFAULT_PRIORITY);
1020 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371021 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361022 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371023 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361024 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1025 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1026 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371027 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121028 Initialize();
1029
1030 request_.method = "GET";
rchcd379012017-04-12 21:53:321031 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121032
xunjieli5fafe142016-03-23 23:32:541033 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271034 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541035 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121036 EXPECT_EQ(OK,
1037 stream_->SendRequest(headers_, &response_, callback_.callback()));
1038
1039 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491040 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1042 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121043
rch1c5b74a2016-06-23 22:10:551044 QuicConnectionCloseFrame frame;
1045 frame.error_code = QUIC_PEER_GOING_AWAY;
1046 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121047
1048 NetErrorDetails details;
1049 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
1050 stream_->PopulateNetErrorDetails(&details);
1051 EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
1052}
1053
Ryan Hamiltone316e482017-08-17 02:48:531054TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511055 // By default the test setup defaults handshake to be confirmed. Manually set
1056 // it to be not confirmed.
rch617e0652017-04-26 17:57:511057 crypto_client_stream_factory_.set_handshake_mode(
1058 MockCryptoClientStream::ZERO_RTT);
1059
zhongyica364fbb2015-12-12 03:39:121060 SetRequest("GET", "/", DEFAULT_PRIORITY);
1061 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371062 QuicStreamOffset header_stream_offset = 0;
fayang3bcb8b502016-12-07 21:44:371063 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361064 1, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1065 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1066 &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:121067 Initialize();
1068
1069 request_.method = "GET";
rchcd379012017-04-12 21:53:321070 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121071
xunjieli5fafe142016-03-23 23:32:541072 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271073 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541074 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121075 EXPECT_EQ(OK,
1076 stream_->SendRequest(headers_, &response_, callback_.callback()));
1077
1078 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491079 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011080 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1081 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121082
rch1c5b74a2016-06-23 22:10:551083 QuicConnectionCloseFrame frame;
1084 frame.error_code = QUIC_PEER_GOING_AWAY;
1085 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121086
1087 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121088 stream_->PopulateNetErrorDetails(&details);
Ryan Hamiltone316e482017-08-17 02:48:531089 EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121090}
1091
rch11a114a2014-09-04 23:41:591092// Regression test for http://crbug.com/409871
1093TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1094 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451095 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371096 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361097 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371098 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361099 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1100 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1101 &header_stream_offset));
rch11a114a2014-09-04 23:41:591102 Initialize();
1103
1104 request_.method = "GET";
rchcd379012017-04-12 21:53:321105 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591106
xunjieli5fafe142016-03-23 23:32:541107 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271108 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541109 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591110
rjshaded5ced072015-12-18 19:26:021111 EXPECT_EQ(OK,
1112 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591113
jri78ec06a2016-03-31 18:19:401114 session_->connection()->CloseConnection(
1115 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591116
1117 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101118
1119 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451120 // headers and payload.
1121 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1122 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101123 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591124}
1125
[email protected]1e960032013-12-20 19:00:201126TEST_P(QuicHttpStreamTest, SendPostRequest) {
1127 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451128 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371129 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361130 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371131 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361132 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1133 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1134 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371135 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, kUploadData));
wangyix6444ffe2017-04-25 17:49:491136 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]f702d572012-12-04 15:56:201137
1138 Initialize();
1139
danakjad1777e2016-04-16 00:56:421140 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191141 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071142 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121143 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191144 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201145 request_.method = "POST";
rchcd379012017-04-12 21:53:321146 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121147 request_.upload_data_stream = upload_data_stream_.get();
tfarina42834112016-09-22 13:38:201148 ASSERT_THAT(request_.upload_data_stream->Init(CompletionCallback(),
1149 NetLogWithSource()),
1150 IsOk());
[email protected]f702d572012-12-04 15:56:201151
xunjieli5fafe142016-03-23 23:32:541152 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271153 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541154 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021155 EXPECT_EQ(OK,
1156 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201157
1158 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491159 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:201160
1161 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071162 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451163 size_t spdy_response_headers_frame_length;
1164 ProcessPacket(ConstructResponseHeadersPacket(
1165 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201166
rchfb47f712017-05-21 03:24:001167 // The headers have already arrived.
1168 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361169 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201170 EXPECT_EQ(200, response_.headers->response_code());
1171 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1172
1173 // Send the response body.
1174 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581175 ProcessPacket(ConstructServerDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:201176 // Since the body has already arrived, this should return immediately.
1177 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1178 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1179 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291180 EXPECT_EQ(0,
1181 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1182 callback_.callback()));
1183
1184 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1185 EXPECT_TRUE(AtEof());
1186
1187 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1188 // headers and payload.
1189 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1190 strlen(kUploadData)),
1191 stream_->GetTotalSentBytes());
1192 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1193 strlen(kResponseBody)),
1194 stream_->GetTotalReceivedBytes());
1195}
1196
1197TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1198 SetRequest("POST", "/", DEFAULT_PRIORITY);
1199 size_t spdy_request_headers_frame_length;
1200 QuicStreamOffset header_stream_offset = 0;
1201 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
1202 AddWrite(InnerConstructRequestHeadersPacket(
1203 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1204 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1205 &header_stream_offset));
1206 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, kUploadData));
1207 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
1208
1209 Initialize();
1210
1211 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191212 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291213 kUploadData, strlen(kUploadData)));
1214 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191215 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291216 request_.method = "POST";
1217 request_.url = GURL("https://www.example.org/");
1218 request_.upload_data_stream = upload_data_stream_.get();
1219 ASSERT_THAT(request_.upload_data_stream->Init(CompletionCallback(),
1220 NetLogWithSource()),
1221 IsOk());
1222
1223 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271224 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291225 net_log_.bound(), callback_.callback()));
1226 EXPECT_EQ(OK,
1227 stream_->SendRequest(headers_, &response_, callback_.callback()));
1228
1229 // Ack both packets in the request.
1230 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
1231
1232 // Send the response headers (but not the body).
1233 SetResponse("200 OK", string());
1234 size_t spdy_response_headers_frame_length;
1235 ProcessPacket(ConstructResponseHeadersPacket(
1236 2, !kFin, &spdy_response_headers_frame_length));
1237
1238 // The headers have already arrived.
1239 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1240 ASSERT_TRUE(response_.headers.get());
1241 EXPECT_EQ(200, response_.headers->response_code());
1242 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1243
1244 // Send the response body.
1245 const char kResponseBody[] = "Hello world!";
1246 ProcessPacket(ConstructServerDataPacket(3, false, !kFin, 0, kResponseBody));
1247 // Since the body has already arrived, this should return immediately.
1248 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1249 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1250 callback_.callback()));
1251 ProcessPacket(ConstructServerDataPacket(4, false, kFin,
1252 arraysize(kResponseBody) - 1, ""));
1253 EXPECT_EQ(0,
1254 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1255 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201256
1257 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1258 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101259
1260 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451261 // headers and payload.
1262 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1263 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101264 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451265 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1266 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101267 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201268}
1269
[email protected]1e960032013-12-20 19:00:201270TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1271 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471272 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451273 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371274 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361275 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371276 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361277 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1278 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1279 &header_stream_offset));
rjshaded5ced072015-12-18 19:26:021280 AddWrite(
fayang3bcb8b502016-12-07 21:44:371281 ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
1282 AddWrite(ConstructClientDataPacket(4, kIncludeVersion, kFin, chunk_size,
alyssar2adf3ac2016-05-03 17:12:581283 kUploadData));
wangyix6444ffe2017-04-25 17:49:491284 AddWrite(ConstructClientAckPacket(5, 3, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471285 Initialize();
1286
Jeremy Roman0579ed62017-08-29 15:56:191287 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121288 auto* chunked_upload_stream =
1289 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1290 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471291
1292 request_.method = "POST";
rchcd379012017-04-12 21:53:321293 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121294 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071295 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201296 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471297
xunjieli5fafe142016-03-23 23:32:541298 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271299 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541300 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021301 ASSERT_EQ(ERR_IO_PENDING,
1302 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471303
rch97827ee2017-05-24 23:49:121304 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011305 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471306
1307 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491308 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]c9e49a02013-02-26 05:56:471309
1310 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071311 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451312 size_t spdy_response_headers_frame_length;
1313 ProcessPacket(ConstructResponseHeadersPacket(
1314 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471315
rchfb47f712017-05-21 03:24:001316 // The headers have already arrived.
1317 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361318 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471319 EXPECT_EQ(200, response_.headers->response_code());
1320 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1321
1322 // Send the response body.
1323 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581324 ProcessPacket(ConstructServerDataPacket(
1325 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471326
1327 // Since the body has already arrived, this should return immediately.
1328 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1329 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1330 callback_.callback()));
1331
1332 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1333 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101334
1335 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451336 // headers and payload.
1337 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1338 strlen(kUploadData) * 2),
sclittle1edeeb22015-09-02 20:46:101339 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451340 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1341 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101342 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471343}
1344
[email protected]16ba7742014-08-22 00:57:251345TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1346 SetRequest("POST", "/", DEFAULT_PRIORITY);
1347 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451348 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371349 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361350 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371351 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361352 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1353 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1354 &header_stream_offset));
alyssar2adf3ac2016-05-03 17:12:581355 AddWrite(
fayang3bcb8b502016-12-07 21:44:371356 ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
1357 AddWrite(ConstructClientDataPacket(4, kIncludeVersion, kFin, chunk_size, ""));
wangyix6444ffe2017-04-25 17:49:491358 AddWrite(ConstructClientAckPacket(5, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251359 Initialize();
1360
Jeremy Roman0579ed62017-08-29 15:56:191361 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121362 auto* chunked_upload_stream =
1363 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1364 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251365
1366 request_.method = "POST";
rchcd379012017-04-12 21:53:321367 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121368 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071369 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201370 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251371
xunjieli5fafe142016-03-23 23:32:541372 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271373 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541374 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021375 ASSERT_EQ(ERR_IO_PENDING,
1376 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251377
rch97827ee2017-05-24 23:49:121378 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011379 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251380
wangyix6444ffe2017-04-25 17:49:491381 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251382
1383 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071384 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451385 size_t spdy_response_headers_frame_length;
1386 ProcessPacket(ConstructResponseHeadersPacket(
1387 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251388
rchfb47f712017-05-21 03:24:001389 // The headers have already arrived.
1390 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251391 ASSERT_TRUE(response_.headers.get());
1392 EXPECT_EQ(200, response_.headers->response_code());
1393 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1394
1395 // Send the response body.
1396 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581397 ProcessPacket(ConstructServerDataPacket(
1398 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251399
rchb27683c2015-07-29 23:53:501400 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251401 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1402 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1403 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251404 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1405 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101406
1407 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451408 // headers and payload.
1409 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1410 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101411 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451412 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1413 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101414 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251415}
1416
1417TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1418 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451419 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371420 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361421 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371422 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361423 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1424 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1425 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371426 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, ""));
wangyix6444ffe2017-04-25 17:49:491427 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251428 Initialize();
1429
Jeremy Roman0579ed62017-08-29 15:56:191430 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121431 auto* chunked_upload_stream =
1432 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251433
1434 request_.method = "POST";
rchcd379012017-04-12 21:53:321435 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121436 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071437 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201438 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251439
xunjieli5fafe142016-03-23 23:32:541440 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271441 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541442 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021443 ASSERT_EQ(ERR_IO_PENDING,
1444 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251445
rch97827ee2017-05-24 23:49:121446 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011447 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251448
wangyix6444ffe2017-04-25 17:49:491449 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251450
1451 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071452 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451453 size_t spdy_response_headers_frame_length;
1454 ProcessPacket(ConstructResponseHeadersPacket(
1455 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251456
rchfb47f712017-05-21 03:24:001457 // The headers have already arrived.
1458 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251459 ASSERT_TRUE(response_.headers.get());
1460 EXPECT_EQ(200, response_.headers->response_code());
1461 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1462
1463 // Send the response body.
1464 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581465 ProcessPacket(ConstructServerDataPacket(
1466 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251467
rchb27683c2015-07-29 23:53:501468 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251469 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1470 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1471 callback_.callback()));
1472
1473 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1474 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101475
1476 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451477 // headers and payload.
1478 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1479 stream_->GetTotalSentBytes());
1480 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1481 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101482 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251483}
1484
[email protected]1e960032013-12-20 19:00:201485TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1486 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451487 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371488 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361489 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371490 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361491 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1492 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1493 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371494 AddWrite(ConstructAckAndRstStreamPacket(3));
[email protected]63534512012-12-23 18:49:001495 Initialize();
1496
1497 request_.method = "GET";
rchcd379012017-04-12 21:53:321498 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001499
xunjieli5fafe142016-03-23 23:32:541500 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271501 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541502 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021503 EXPECT_EQ(OK,
1504 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001505
1506 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491507 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
rchfb47f712017-05-21 03:24:001508 EXPECT_THAT(stream_->ReadResponseHeaders(
1509 base::Bind(&QuicHttpStreamTest::CloseStream,
1510 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011511 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001512
1513 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201514 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001515 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001516 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291517 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001518
fdoray92e35a72016-06-10 15:54:551519 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501520
[email protected]63534512012-12-23 18:49:001521 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101522
1523 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451524 // headers and payload.
1525 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1526 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001527 // The stream was closed after receiving the headers.
1528 EXPECT_EQ(static_cast<int64_t>(response_size),
1529 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001530}
1531
[email protected]1e960032013-12-20 19:00:201532TEST_P(QuicHttpStreamTest, Priority) {
1533 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451534 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371535 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361536 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371537 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361538 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin, MEDIUM,
fayang3bcb8b502016-12-07 21:44:371539 &spdy_request_headers_frame_length, &header_stream_offset));
[email protected]24e5bc52013-09-18 15:36:581540 Initialize();
1541
1542 request_.method = "GET";
rchcd379012017-04-12 21:53:321543 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581544
Steven Valdezb4ff0412018-01-18 22:39:271545 EXPECT_EQ(OK,
1546 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1547 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581548
1549 // Check that priority is highest.
rch08e198572017-05-09 16:56:551550 QuicChromiumClientStream::Handle* reliable_stream =
rch12fef552016-01-15 16:26:311551 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
[email protected]24e5bc52013-09-18 15:36:581552 DCHECK(reliable_stream);
fayanga64c1a92016-02-13 01:55:581553 DCHECK_EQ(kV3HighestPriority, reliable_stream->priority());
[email protected]24e5bc52013-09-18 15:36:581554
rjshaded5ced072015-12-18 19:26:021555 EXPECT_EQ(OK,
1556 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581557
1558 // Check that priority has now dropped back to MEDIUM.
ianswett0888cff2015-11-24 17:42:161559 DCHECK_EQ(MEDIUM,
fayanga64c1a92016-02-13 01:55:581560 ConvertQuicPriorityToRequestPriority(reliable_stream->priority()));
[email protected]24e5bc52013-09-18 15:36:581561
1562 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491563 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011564 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1565 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581566
1567 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201568 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001569 size_t response_size = 0;
1570 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581571
rchfb47f712017-05-21 03:24:001572 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501573
[email protected]24e5bc52013-09-18 15:36:581574 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101575
1576 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451577 // headers and payload.
1578 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1579 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001580 EXPECT_EQ(static_cast<int64_t>(response_size),
1581 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581582}
1583
xunjieli8dff50b2016-07-22 14:19:061584TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1585 SetRequest("POST", "/", DEFAULT_PRIORITY);
1586 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371587 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361588 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371589 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361590 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1591 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1592 &header_stream_offset));
xunjieli8dff50b2016-07-22 14:19:061593 AddWrite(
fayang3bcb8b502016-12-07 21:44:371594 ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
xunjieli8dff50b2016-07-22 14:19:061595 // Second data write will result in a synchronous failure which will close
1596 // the session.
1597 AddWrite(SYNCHRONOUS, ERR_FAILED);
1598 Initialize();
1599
Jeremy Roman0579ed62017-08-29 15:56:191600 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121601 auto* chunked_upload_stream =
1602 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061603
1604 request_.method = "POST";
rchcd379012017-04-12 21:53:321605 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121606 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061607 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201608 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061609
1610 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121611 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061612 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271613 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061614 net_log_.bound(), callback_.callback()));
1615 QuicHttpStream* stream = stream_.get();
1616 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1617 // SendRequest() completes asynchronously after the final chunk is added.
1618 ASSERT_EQ(ERR_IO_PENDING,
1619 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121620 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061621 int rv = callback_.WaitForResult();
1622 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, rv);
1623}
1624
rtenneti15656ae2016-01-23 03:05:031625TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1626 SetRequest("POST", "/", DEFAULT_PRIORITY);
fayang3bcb8b502016-12-07 21:44:371627 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361628 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031629 AddWrite(SYNCHRONOUS, ERR_FAILED);
1630 Initialize();
1631
Jeremy Roman0579ed62017-08-29 15:56:191632 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rtenneti15656ae2016-01-23 03:05:031633
1634 request_.method = "POST";
rchcd379012017-04-12 21:53:321635 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121636 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031637 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201638 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031639
xunjieli5fafe142016-03-23 23:32:541640 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271641 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541642 net_log_.bound(), callback_.callback()));
rtenneti15656ae2016-01-23 03:05:031643 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1644 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241645
1646 EXPECT_LE(0, stream_->GetTotalSentBytes());
1647 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031648}
1649
1650TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1651 SetRequest("POST", "/", DEFAULT_PRIORITY);
1652 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371653 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361654 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371655 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361656 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1657 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1658 &header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031659 AddWrite(SYNCHRONOUS, ERR_FAILED);
1660 Initialize();
1661
Jeremy Roman0579ed62017-08-29 15:56:191662 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121663 auto* chunked_upload_stream =
1664 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031665 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121666 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
rtenneti15656ae2016-01-23 03:05:031667
1668 request_.method = "POST";
rchcd379012017-04-12 21:53:321669 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121670 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031671 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201672 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031673
xunjieli5fafe142016-03-23 23:32:541674 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271675 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541676 net_log_.bound(), callback_.callback()));
rtenneti15656ae2016-01-23 03:05:031677 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1678 stream_->SendRequest(headers_, &response_, callback_.callback()));
1679}
1680
ckrasic3865ee0f2016-02-29 22:04:561681TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1682 SetRequest("GET", "/", DEFAULT_PRIORITY);
1683 Initialize();
1684
1685 // Initialize the first stream, for receiving the promise on.
1686 request_.method = "GET";
rchcd379012017-04-12 21:53:321687 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561688
xunjieli5fafe142016-03-23 23:32:541689 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271690 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541691 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561692
1693 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1694 // packet, but does it matter?
1695 ReceivePromise(promise_id_);
1696 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1697
1698 request_.url = GURL(promise_url_);
1699
1700 // Make the second stream that will exercise the first step of the
1701 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271702 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1703 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1704 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561705
1706 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251707 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561708 size_t spdy_response_headers_frame_length;
1709 ProcessPacket(InnerConstructResponseHeadersPacket(
1710 1, promise_id_, false, &spdy_response_headers_frame_length));
1711
1712 // Receive the promised response body.
1713 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581714 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1715 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561716
1717 // Now sending a matching request will have successful rendezvous
1718 // with the promised stream.
1719 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1720 callback_.callback()));
1721
1722 EXPECT_EQ(
1723 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1724 ->id(),
1725 promise_id_);
1726
1727 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011728 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1729 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561730
1731 // As will be the body.
1732 EXPECT_EQ(
1733 static_cast<int>(strlen(kResponseBody)),
1734 promised_stream_->ReadResponseBody(
1735 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1736 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1737 EXPECT_TRUE(AtEof());
1738
1739 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1740 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1741 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1742 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1743 strlen(kResponseBody)),
1744 promised_stream_->GetTotalReceivedBytes());
1745}
1746
1747TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
1748 SetRequest("GET", "/", DEFAULT_PRIORITY);
1749 Initialize();
1750
1751 // Initialize the first stream, for receiving the promise on.
1752 request_.method = "GET";
rchcd379012017-04-12 21:53:321753 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561754
xunjieli5fafe142016-03-23 23:32:541755 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271756 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541757 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561758
1759 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1760 // packet, but does it matter?
1761 ReceivePromise(promise_id_);
1762 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1763
1764 request_.url = GURL(promise_url_);
1765
1766 // Make the second stream that will exercise the first step of the
1767 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271768 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1769 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1770 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561771
1772 // Now sending a matching request will rendezvous with the promised
1773 // stream, but pending secondary validation.
1774 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1775 headers_, &response_, callback_.callback()));
1776
1777 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251778 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561779 size_t spdy_response_headers_frame_length;
1780 ProcessPacket(InnerConstructResponseHeadersPacket(
1781 1, promise_id_, false, &spdy_response_headers_frame_length));
1782
1783 // Receive the promised response body.
1784 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581785 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1786 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561787
fdoray92e35a72016-06-10 15:54:551788 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561789
1790 // Rendezvous should have succeeded now, so the promised stream
1791 // should point at our push stream, and we should be able read
1792 // headers and data from it.
robpercival214763f2016-07-01 23:27:011793 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:561794
1795 EXPECT_EQ(
1796 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1797 ->id(),
1798 promise_id_);
1799
robpercival214763f2016-07-01 23:27:011800 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1801 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561802
1803 EXPECT_EQ(
1804 static_cast<int>(strlen(kResponseBody)),
1805 promised_stream_->ReadResponseBody(
1806 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1807
1808 // Callback should return
1809 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1810 EXPECT_TRUE(AtEof());
1811
1812 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1813 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1814 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1815 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1816 strlen(kResponseBody)),
1817 promised_stream_->GetTotalReceivedBytes());
1818}
1819
ckrasic2c63f9b2016-08-16 23:54:071820// Verify fix for crbug.com/637349
1821TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
1822 SetRequest("GET", "/", DEFAULT_PRIORITY);
1823 Initialize();
1824
1825 // Initialize the first stream, for receiving the promise on.
1826 request_.method = "GET";
rchcd379012017-04-12 21:53:321827 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:071828
1829 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271830 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:071831 net_log_.bound(), callback_.callback()));
1832
1833 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1834 // packet, but does it matter?
1835 ReceivePromise(promise_id_);
1836 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1837
1838 request_.url = GURL(promise_url_);
1839
1840 // Make the second stream that will exercise the first step of the
1841 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271842 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1843 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1844 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:071845
1846 // Now sending a matching request will rendezvous with the promised
1847 // stream, but pending secondary validation.
1848 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1849 headers_, &response_, callback_.callback()));
1850
1851 base::RunLoop().RunUntilIdle();
1852
1853 // Cause of FinalValidation() crash as per bug.
1854 promised_stream_.reset();
1855
1856 // Receive the promised response headers.
1857 response_headers_ = promised_response_.Clone();
1858 size_t spdy_response_headers_frame_length;
1859 ProcessPacket(InnerConstructResponseHeadersPacket(
1860 1, promise_id_, false, &spdy_response_headers_frame_length));
1861}
1862
ckrasic3865ee0f2016-02-29 22:04:561863TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
1864 SetRequest("GET", "/", DEFAULT_PRIORITY);
1865 Initialize();
1866
1867 // Initialize the first stream, for receiving the promise on.
1868 request_.method = "GET";
rchcd379012017-04-12 21:53:321869 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561870
xunjieli5fafe142016-03-23 23:32:541871 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271872 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541873 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561874
1875 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1876 // packet, but does it matter?
1877
1878 push_promise_[":authority"] = "mail.example.org";
Yixin Wang81c11182018-02-05 20:09:571879 promise_url_ = SpdyUtils::GetPromisedUrlFromHeaderBlock(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:561880
1881 ReceivePromise(promise_id_);
1882 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1883
1884 request_.url = GURL(promise_url_);
1885
1886 // Make the second stream that will exercise the first step of the
1887 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271888 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1889 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1890 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561891
1892 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251893 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561894 size_t spdy_response_headers_frame_length;
1895 ProcessPacket(InnerConstructResponseHeadersPacket(
1896 1, promise_id_, false, &spdy_response_headers_frame_length));
1897
1898 // Receive the promised response body.
1899 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581900 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1901 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561902
1903 // Now sending a matching request will have successful rendezvous
1904 // with the promised stream.
1905 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1906 callback_.callback()));
1907
1908 EXPECT_EQ(
1909 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1910 ->id(),
1911 promise_id_);
1912
1913 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011914 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1915 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561916
1917 // As will be the body.
1918 EXPECT_EQ(
1919 static_cast<int>(strlen(kResponseBody)),
1920 promised_stream_->ReadResponseBody(
1921 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1922 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1923 EXPECT_TRUE(AtEof());
1924
1925 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1926 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1927 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1928 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1929 strlen(kResponseBody)),
1930 promised_stream_->GetTotalReceivedBytes());
1931}
1932
1933TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
1934 SetRequest("GET", "/", DEFAULT_PRIORITY);
1935 Initialize();
1936
1937 // Initialize the first stream, for receiving the promise on.
1938 request_.method = "GET";
rchcd379012017-04-12 21:53:321939 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561940
xunjieli5fafe142016-03-23 23:32:541941 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271942 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541943 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561944
1945 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1946 // packet, but does it matter?
1947 push_promise_[":authority"] = "www.notexample.org";
Yixin Wang81c11182018-02-05 20:09:571948 promise_url_ = SpdyUtils::GetPromisedUrlFromHeaderBlock(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:561949
1950 ReceivePromise(promise_id_);
1951 // The promise will have been rejected because the cert doesn't
1952 // match.
1953 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
1954}
1955
1956TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
1957 SetRequest("GET", "/", DEFAULT_PRIORITY);
1958 Initialize();
1959
1960 // Initialize the first stream, for receiving the promise on.
1961 request_.method = "GET";
rchcd379012017-04-12 21:53:321962 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561963
xunjieli5fafe142016-03-23 23:32:541964 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271965 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541966 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561967
1968 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:561969
1970 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1971 // packet, but does it matter?
1972 ReceivePromise(promise_id_);
1973 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1974
1975 request_.url = GURL(promise_url_);
1976
1977 // Make the second stream that will exercise the first step of the
1978 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271979 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1980 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1981 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561982
1983 headers_.SetHeader("accept-encoding", "gzip");
1984
1985 // Now sending a matching request will rendezvous with the promised
1986 // stream, but pending secondary validation.
1987 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1988 headers_, &response_, callback_.callback()));
1989
1990 // Receive the promised response headers.
1991 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:251992 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561993 size_t spdy_response_headers_frame_length;
1994 ProcessPacket(InnerConstructResponseHeadersPacket(
1995 1, promise_id_, false, &spdy_response_headers_frame_length));
1996
1997 // Receive the promised response body.
1998 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581999 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
2000 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562001
fdoray92e35a72016-06-10 15:54:552002 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562003
2004 // Rendezvous should have succeeded now, so the promised stream
2005 // should point at our push stream, and we should be able read
2006 // headers and data from it.
robpercival214763f2016-07-01 23:27:012007 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562008
2009 EXPECT_EQ(
2010 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2011 ->id(),
2012 promise_id_);
2013
robpercival214763f2016-07-01 23:27:012014 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2015 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562016
2017 EXPECT_EQ(
2018 static_cast<int>(strlen(kResponseBody)),
2019 promised_stream_->ReadResponseBody(
2020 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2021
2022 // Callback should return
2023 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2024 EXPECT_TRUE(AtEof());
2025
2026 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2027 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2028 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2029 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
2030 strlen(kResponseBody)),
2031 promised_stream_->GetTotalReceivedBytes());
2032}
2033
2034TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2035 SetRequest("GET", "/", DEFAULT_PRIORITY);
2036 request_headers_[":scheme"] = "https";
2037 request_headers_[":path"] = "/bar";
2038 request_headers_["accept-encoding"] = "sdch";
2039
2040 size_t spdy_request_header_frame_length;
fayang3bcb8b502016-12-07 21:44:372041 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362042 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372043 AddWrite(ConstructClientRstStreamVaryMismatchPacket(2));
ckrasic3865ee0f2016-02-29 22:04:562044 AddWrite(InnerConstructRequestHeadersPacket(
fayang3bcb8b502016-12-07 21:44:372045 3, stream_id_ + 2, !kIncludeVersion, kFin, DEFAULT_PRIORITY,
2046 &spdy_request_header_frame_length, &header_stream_offset));
wangyix6444ffe2017-04-25 17:49:492047 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
fayang3bcb8b502016-12-07 21:44:372048 AddWrite(ConstructClientRstStreamCancelledPacket(5));
ckrasic3865ee0f2016-02-29 22:04:562049 Initialize();
2050
2051 // Initialize the first stream, for receiving the promise on.
2052 request_.method = "GET";
rchcd379012017-04-12 21:53:322053 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562054
xunjieli5fafe142016-03-23 23:32:542055 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272056 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542057 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562058
2059 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562060
2061 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2062 // packet, but does it matter?
2063 ReceivePromise(promise_id_);
2064 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2065
2066 request_.url = GURL(promise_url_);
2067
2068 // Make the second stream that will exercise the first step of the
2069 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272070 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2071 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2072 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562073
2074 headers_.SetHeader("accept-encoding", "sdch");
2075
2076 // Now sending a matching request will rendezvous with the promised
2077 // stream, but pending secondary validation.
2078 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2079 headers_, &response_, callback_.callback()));
2080
2081 // Receive the promised response headers.
2082 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252083 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562084 size_t spdy_response_headers_frame_length;
2085 ProcessPacket(InnerConstructResponseHeadersPacket(
2086 1, promise_id_, false, &spdy_response_headers_frame_length));
2087
fdoray92e35a72016-06-10 15:54:552088 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562089
2090 // Rendezvous should have failed due to vary mismatch, so the
2091 // promised stream should have been aborted, and instead we have a
2092 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012093 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562094
2095 // Not a server-initiated stream.
2096 EXPECT_NE(
2097 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2098 ->id(),
2099 promise_id_);
2100
2101 // Instead, a new client-initiated stream.
2102 EXPECT_EQ(
2103 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2104 ->id(),
2105 stream_id_ + 2);
2106
2107 // After rendezvous failure, the push stream has been cancelled.
2108 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2109
2110 // The rest of the test verifies that the retried as
2111 // client-initiated version of |promised_stream_| works as intended.
2112
2113 // Ack the request.
wangyix6444ffe2017-04-25 17:49:492114 ProcessPacket(ConstructServerAckPacket(2, 0, 0, 0));
ckrasic3865ee0f2016-02-29 22:04:562115
bnc614a92d32016-04-04 13:56:072116 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562117 size_t spdy_response_header_frame_length;
2118 ProcessPacket(InnerConstructResponseHeadersPacket(
2119 3, stream_id_ + 2, kFin, &spdy_response_header_frame_length));
2120
fdoray92e35a72016-06-10 15:54:552121 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562122
robpercival214763f2016-07-01 23:27:012123 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2124 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562125 ASSERT_TRUE(response_.headers.get());
2126 EXPECT_EQ(404, response_.headers->response_code());
2127 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2128 EXPECT_FALSE(response_.response_time.is_null());
2129 EXPECT_FALSE(response_.request_time.is_null());
2130
2131 // There is no body, so this should return immediately.
2132 EXPECT_EQ(
2133 0, promised_stream_->ReadResponseBody(
2134 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2135 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2136
2137 stream_->Close(true);
2138
2139 EXPECT_TRUE(AtEof());
2140
2141 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
2142 // headers and payload.
2143 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
2144 promised_stream_->GetTotalSentBytes());
2145 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
2146 promised_stream_->GetTotalReceivedBytes());
2147}
2148
maksim.sisov84e20c92016-06-23 08:49:342149TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2150 SetRequest("POST", "/", DEFAULT_PRIORITY);
2151 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:372152 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362153 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372154 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:362155 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
2156 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2157 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372158 AddWrite(ConstructClientRstStreamErrorPacket(3, kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342159
2160 Initialize();
2161
Jeremy Roman0579ed62017-08-29 15:56:192162 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342163 ReadErrorUploadDataStream::FailureMode::SYNC);
2164 request_.method = "POST";
rchcd379012017-04-12 21:53:322165 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122166 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342167 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202168 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342169
2170 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272171 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342172 net_log_.bound(), callback_.callback()));
2173
2174 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012175 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342176
2177 EXPECT_TRUE(AtEof());
2178
2179 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2180 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2181 stream_->GetTotalSentBytes());
2182 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2183}
2184
2185TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2186 SetRequest("POST", "/", DEFAULT_PRIORITY);
2187 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:372188 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362189 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372190 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:362191 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
2192 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2193 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372194 AddWrite(ConstructClientRstStreamErrorPacket(3, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342195
2196 Initialize();
2197
Jeremy Roman0579ed62017-08-29 15:56:192198 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342199 ReadErrorUploadDataStream::FailureMode::ASYNC);
2200 request_.method = "POST";
rchcd379012017-04-12 21:53:322201 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122202 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342203 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202204 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342205
2206 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272207 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342208 net_log_.bound(), callback_.callback()));
2209
2210 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2211
wangyix6444ffe2017-04-25 17:49:492212 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
maksim.sisov84e20c92016-06-23 08:49:342213 SetResponse("200 OK", string());
2214
robpercival214763f2016-07-01 23:27:012215 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2216 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342217
2218 EXPECT_TRUE(AtEof());
2219
2220 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2221 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2222 stream_->GetTotalSentBytes());
2223 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2224}
2225
[email protected]f702d572012-12-04 15:56:202226} // namespace test
[email protected]f702d572012-12-04 15:56:202227} // namespace net