blob: e8a292b6166bd501d41ff691078419a682cdb658 [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)),
Paul Jensen8e3c5d32018-02-19 17:06:33312 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
313 PRIVACY_MODE_DISABLED, SocketTag()),
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
Yixin Wangb470bc882018-02-15 18:43:57535 std::unique_ptr<QuicReceivedPacket> ConstructClientPriorityPacket(
536 QuicPacketNumber packet_number,
537 bool should_include_version,
538 QuicStreamId id,
539 QuicStreamId parent_stream_id,
540 RequestPriority request_priority,
541 QuicStreamOffset* header_stream_offset) {
542 return client_maker_.MakePriorityPacket(
543 packet_number, should_include_version, id, parent_stream_id,
544 ConvertRequestPriorityToQuicPriority(request_priority),
545 header_stream_offset);
546 }
547
rch5cb522462017-04-25 20:18:36548 std::unique_ptr<QuicReceivedPacket> ConstructInitialSettingsPacket(
fayang3bcb8b502016-12-07 21:44:37549 QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36550 return client_maker_.MakeInitialSettingsPacket(1, offset);
fayang3bcb8b502016-12-07 21:44:37551 }
552
ckrasic3865ee0f2016-02-29 22:04:56553 void ReceivePromise(QuicStreamId id) {
ckrasic32b17dcd2016-10-31 06:15:35554 auto headers = AsHeaderList(push_promise_);
rch08e198572017-05-09 16:56:55555 QuicChromiumClientStream::Handle* stream =
ckrasic3865ee0f2016-02-29 22:04:56556 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
ckrasic32b17dcd2016-10-31 06:15:35557 stream->OnPromiseHeaderList(id, headers.uncompressed_header_bytes(),
558 headers);
ckrasic3865ee0f2016-02-29 22:04:56559 }
560
xunjieli84adaab2016-09-20 01:12:28561 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37562 bool session_reused) {
563 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28564 if (session_reused) {
565 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
566 } else {
567 ExpectConnectTimingHasTimes(
568 load_timing_info.connect_timing,
569 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
570 }
571 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37572 }
573
ckrasicbf2f59c2017-05-04 23:54:36574 QuicStreamId GetNthClientInitiatedStreamId(int n) {
Yixin Wang079ad542018-01-11 04:06:05575 return test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36576 }
577
578 QuicStreamId GetNthServerInitiatedStreamId(int n) {
Yixin Wang079ad542018-01-11 04:06:05579 return test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36580 }
581
Yixin Wang079ad542018-01-11 04:06:05582 const QuicTransportVersion version_;
583 const bool client_headers_include_h2_stream_dependency_;
584
xunjieli5fafe142016-03-23 23:32:54585 BoundTestNetLog net_log_;
[email protected]fee17f72013-02-03 07:47:41586 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20587 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42588 std::unique_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20589 MockClock clock_;
590 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42591 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07592 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
ckrasica7fd1242016-05-14 20:36:01593 testing::StrictMock<MockQuicConnectionVisitor> visitor_;
rch97827ee2017-05-24 23:49:12594 std::unique_ptr<UploadDataStream> upload_data_stream_;
danakjad1777e2016-04-16 00:56:42595 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15596 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42597 std::unique_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01598 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20599 TestCompletionCallback callback_;
600 HttpRequestInfo request_;
601 HttpRequestHeaders headers_;
602 HttpResponseInfo response_;
603 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20604 SpdyHeaderBlock request_headers_;
605 SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07606 string request_data_;
607 string response_data_;
ckrasic244375a32016-02-04 21:21:22608 QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20609
ckrasic3865ee0f2016-02-29 22:04:56610 // For server push testing
danakjad1777e2016-04-16 00:56:42611 std::unique_ptr<QuicHttpStream> promised_stream_;
ckrasic3865ee0f2016-02-29 22:04:56612 SpdyHeaderBlock push_promise_;
613 SpdyHeaderBlock promised_response_;
614 const QuicStreamId promise_id_;
615 string promise_url_;
ckrasic3865ee0f2016-02-29 22:04:56616 const QuicStreamId stream_id_;
617
[email protected]3aa9ca72014-02-27 19:39:43618 const QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58619 QuicTestPacketMaker client_maker_;
620 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20621 IPEndPoint self_addr_;
622 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58623 MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20624 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05625 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42626 std::unique_ptr<StaticSocketDataProvider> socket_data_;
[email protected]f702d572012-12-04 15:56:20627 std::vector<PacketToWrite> writes_;
ckrasic3865ee0f2016-02-29 22:04:56628 QuicStreamOffset response_offset_;
[email protected]f702d572012-12-04 15:56:20629};
630
Yixin Wang079ad542018-01-11 04:06:05631INSTANTIATE_TEST_CASE_P(
632 VersionIncludeStreamDependencySequnece,
633 QuicHttpStreamTest,
634 ::testing::Combine(::testing::ValuesIn(AllSupportedTransportVersions()),
635 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20636
637TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44638 Initialize();
rtennetibe635732014-10-02 22:51:42639 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20640}
641
mmenkebd84c392015-09-02 14:12:34642TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44643 Initialize();
mmenkebd84c392015-09-02 14:12:34644 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20645}
646
jri231c2972016-03-08 19:50:11647TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
648 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
649 Initialize();
xunjieli5fafe142016-03-23 23:32:54650 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27651 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54652 net_log_.bound(), callback_.callback()));
rch08e198572017-05-09 16:56:55653 QuicChromiumClientStream::Handle* client_stream =
jri231c2972016-03-08 19:50:11654 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
655 EXPECT_FALSE(client_stream->can_migrate());
656}
657
[email protected]1e960032013-12-20 19:00:20658TEST_P(QuicHttpStreamTest, GetRequest) {
659 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45660 size_t spdy_request_header_frame_length;
fayang3bcb8b502016-12-07 21:44:37661 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36662 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37663 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36664 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
665 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
666 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37667
[email protected]f702d572012-12-04 15:56:20668 Initialize();
669
670 request_.method = "GET";
rchcd379012017-04-12 21:53:32671 request_.url = GURL("https://www.example.org/");
[email protected]f702d572012-12-04 15:56:20672
xunjieli100937eb52016-09-15 20:09:37673 // Make sure getting load timing from the stream early does not crash.
674 LoadTimingInfo load_timing_info;
675 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
676
xunjieli5fafe142016-03-23 23:32:54677 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27678 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54679 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02680 EXPECT_EQ(OK,
681 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20682
683 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49684 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:20685
robpercival214763f2016-07-01 23:27:01686 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
687 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20688
bnc614a92d32016-04-04 13:56:07689 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45690 size_t spdy_response_header_frame_length;
691 ProcessPacket(ConstructResponseHeadersPacket(
692 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20693
694 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01695 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36696 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20697 EXPECT_EQ(404, response_.headers->response_code());
698 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53699 EXPECT_FALSE(response_.response_time.is_null());
700 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20701
702 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02703 EXPECT_EQ(0,
704 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
705 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20706 EXPECT_TRUE(stream_->IsResponseBodyComplete());
707 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10708
xunjieli100937eb52016-09-15 20:09:37709 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28710 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37711
sclittle1edeeb22015-09-02 20:46:10712 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45713 // headers and payload.
714 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
715 stream_->GetTotalSentBytes());
716 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
717 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20718}
719
xunjieli100937eb52016-09-15 20:09:37720TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
721 SetRequest("GET", "/", DEFAULT_PRIORITY);
722 size_t spdy_request_header_frame_length;
723
724 QuicStreamOffset offset = 0;
rch5cb522462017-04-25 20:18:36725 AddWrite(ConstructInitialSettingsPacket(&offset));
xunjieli100937eb52016-09-15 20:09:37726 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36727 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
728 DEFAULT_PRIORITY, &spdy_request_header_frame_length, &offset));
xunjieli100937eb52016-09-15 20:09:37729
730 // SetRequest() again for second request as |request_headers_| was moved.
731 SetRequest("GET", "/", DEFAULT_PRIORITY);
732 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36733 3, GetNthClientInitiatedStreamId(1), kIncludeVersion, kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48734 DEFAULT_PRIORITY, GetNthClientInitiatedStreamId(0),
735 &spdy_request_header_frame_length, &offset));
wangyix6444ffe2017-04-25 17:49:49736 AddWrite(ConstructClientAckPacket(4, 3, 1, 1)); // Ack the responses.
xunjieli100937eb52016-09-15 20:09:37737
738 Initialize();
739
740 request_.method = "GET";
rchcd379012017-04-12 21:53:32741 request_.url = GURL("https://www.example.org/");
xunjieli100937eb52016-09-15 20:09:37742 // Start first request.
743 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27744 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37745 net_log_.bound(), callback_.callback()));
746 EXPECT_EQ(OK,
747 stream_->SendRequest(headers_, &response_, callback_.callback()));
748
749 // Start a second request.
Ryan Hamilton6c2a2a82017-12-15 02:06:28750 QuicHttpStream stream2(
751 session_->CreateHandle(HostPortPair("www.example.org", 443)));
xunjieli100937eb52016-09-15 20:09:37752 TestCompletionCallback callback2;
753 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27754 stream2.InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:37755 net_log_.bound(), callback2.callback()));
756 EXPECT_EQ(OK,
757 stream2.SendRequest(headers_, &response_, callback2.callback()));
758
759 // Ack both requests.
wangyix6444ffe2017-04-25 17:49:49760 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli100937eb52016-09-15 20:09:37761
762 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
763 IsError(ERR_IO_PENDING));
764 size_t spdy_response_header_frame_length;
765 SetResponse("200 OK", string());
766 ProcessPacket(InnerConstructResponseHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36767 2, GetNthClientInitiatedStreamId(0), kFin,
768 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37769
770 // Now that the headers have been processed, the callback will return.
771 EXPECT_THAT(callback_.WaitForResult(), IsOk());
772 EXPECT_EQ(200, response_.headers->response_code());
773
774 // There is no body, so this should return immediately.
775 EXPECT_EQ(0,
776 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
777 callback_.callback()));
778 EXPECT_TRUE(stream_->IsResponseBodyComplete());
779
780 LoadTimingInfo load_timing_info;
781 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28782 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37783
784 // SetResponse() again for second request as |response_headers_| was moved.
785 SetResponse("200 OK", string());
786 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
787 IsError(ERR_IO_PENDING));
788
789 ProcessPacket(InnerConstructResponseHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36790 3, GetNthClientInitiatedStreamId(1), kFin,
791 &spdy_response_header_frame_length));
xunjieli100937eb52016-09-15 20:09:37792
793 EXPECT_THAT(callback2.WaitForResult(), IsOk());
794
795 // There is no body, so this should return immediately.
796 EXPECT_EQ(0,
797 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
798 callback2.callback()));
799 EXPECT_TRUE(stream2.IsResponseBodyComplete());
800
801 LoadTimingInfo load_timing_info2;
802 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28803 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37804}
805
xunjieli34291fe12016-03-02 13:58:38806// QuicHttpStream does not currently support trailers. It should ignore
807// trailers upon receiving them.
808TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
809 SetRequest("GET", "/", DEFAULT_PRIORITY);
810 size_t spdy_request_header_frame_length;
fayang3bcb8b502016-12-07 21:44:37811 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36812 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37813 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36814 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
815 DEFAULT_PRIORITY, &spdy_request_header_frame_length,
816 &header_stream_offset));
wangyix6444ffe2017-04-25 17:49:49817 AddWrite(ConstructClientAckPacket(3, 3, 1, 1)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38818
819 Initialize();
820
821 request_.method = "GET";
rchcd379012017-04-12 21:53:32822 request_.url = GURL("https://www.example.org/");
xunjieli34291fe12016-03-02 13:58:38823
xunjieli5fafe142016-03-23 23:32:54824 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27825 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54826 net_log_.bound(), callback_.callback()));
827
xunjieli34291fe12016-03-02 13:58:38828 EXPECT_EQ(OK,
829 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38830 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49831 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
xunjieli34291fe12016-03-02 13:58:38832
robpercival214763f2016-07-01 23:27:01833 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
834 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38835
bnc614a92d32016-04-04 13:56:07836 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38837
838 // Send the response headers.
839 size_t spdy_response_header_frame_length;
840 QuicStreamOffset offset = 0;
841 ProcessPacket(ConstructResponseHeadersPacketWithOffset(
842 2, !kFin, &spdy_response_header_frame_length, &offset));
843 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01844 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38845 ASSERT_TRUE(response_.headers.get());
846 EXPECT_EQ(200, response_.headers->response_code());
847 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
848 EXPECT_FALSE(response_.response_time.is_null());
849 EXPECT_FALSE(response_.request_time.is_null());
850
851 // Send the response body.
852 const char kResponseBody[] = "Hello world!";
853 ProcessPacket(
alyssar2adf3ac2016-05-03 17:12:58854 ConstructServerDataPacket(3, false, !kFin, /*offset=*/0, kResponseBody));
xunjieli34291fe12016-03-02 13:58:38855 SpdyHeaderBlock trailers;
856 size_t spdy_trailers_frame_length;
857 trailers["foo"] = "bar";
xunjieli188bd402016-03-12 00:17:25858 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
xunjieli34291fe12016-03-02 13:58:38859 ProcessPacket(ConstructResponseTrailersPacket(
bnc086b39e12016-06-24 13:05:26860 4, kFin, std::move(trailers), &spdy_trailers_frame_length, &offset));
xunjieli34291fe12016-03-02 13:58:38861
862 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55863 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38864
865 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
866 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
867 callback_.callback()));
868 EXPECT_TRUE(stream_->IsResponseBodyComplete());
869
870 EXPECT_EQ(OK,
871 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
872 callback_.callback()));
873
874 EXPECT_TRUE(stream_->IsResponseBodyComplete());
875 EXPECT_TRUE(AtEof());
876
877 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
878 // headers and payload.
879 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
880 stream_->GetTotalSentBytes());
881 EXPECT_EQ(
882 static_cast<int64_t>(spdy_response_header_frame_length +
883 strlen(kResponseBody) + +spdy_trailers_frame_length),
884 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54885 // Check that NetLog was filled as expected.
886 TestNetLogEntry::List entries;
887 net_log_.GetEntries(&entries);
888 size_t pos = ExpectLogContainsSomewhere(
889 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00890 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
891 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54892 pos = ExpectLogContainsSomewhere(
893 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00894 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
895 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54896 ExpectLogContainsSomewhere(
897 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00898 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
899 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38900}
901
[email protected]3e7dca62013-09-10 16:14:23902// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20903TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
904 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45905 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:37906 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:36907 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:37908 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:36909 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
910 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
911 &header_stream_offset));
[email protected]3e7dca62013-09-10 16:14:23912 Initialize();
913
914 request_.method = "GET";
rchcd379012017-04-12 21:53:32915 request_.url = GURL("https://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:23916
xunjieli5fafe142016-03-23 23:32:54917 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27918 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54919 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02920 EXPECT_EQ(OK,
921 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23922
923 // Ack the request.
wangyix6444ffe2017-04-25 17:49:49924 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23925
robpercival214763f2016-07-01 23:27:01926 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
927 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:23928
bnc086b39e12016-06-24 13:05:26929 response_headers_[":status"] = "200 OK";
930 response_headers_[":version"] = "HTTP/1.1";
931 response_headers_["content-type"] = "text/plain";
932 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23933
sclittlec4dc1a32015-09-24 00:15:45934 size_t spdy_response_headers_frame_length;
935 ProcessPacket(ConstructResponseHeadersPacket(
936 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23937
938 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01939 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:23940 ASSERT_TRUE(response_.headers.get());
941 EXPECT_EQ(200, response_.headers->response_code());
942 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
943
944 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02945 EXPECT_EQ(0,
946 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
947 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23948 EXPECT_TRUE(stream_->IsResponseBodyComplete());
949 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10950
951 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45952 // headers and payload.
953 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
954 stream_->GetTotalSentBytes());
955 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
956 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:23957}
958
rchf9f103cbc2014-08-30 05:28:04959// Regression test for http://crbug.com/409101
960TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
961 SetRequest("GET", "/", DEFAULT_PRIORITY);
962 Initialize();
963
964 request_.method = "GET";
rchcd379012017-04-12 21:53:32965 request_.url = GURL("https://www.example.org/");
rchf9f103cbc2014-08-30 05:28:04966
xunjieli5fafe142016-03-23 23:32:54967 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27968 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54969 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:04970
jri78ec06a2016-03-31 18:19:40971 session_->connection()->CloseConnection(
972 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:04973
974 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:02975 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10976
977 EXPECT_EQ(0, stream_->GetTotalSentBytes());
978 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:04979}
980
rch03b7a202016-02-05 00:54:20981// Regression test for http://crbug.com/584441
982TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
983 SetRequest("GET", "/", DEFAULT_PRIORITY);
984 Initialize();
985
986 request_.method = "GET";
rchcd379012017-04-12 21:53:32987 request_.url = GURL("https://www.example.org/");
rch03b7a202016-02-05 00:54:20988
xunjieli5fafe142016-03-23 23:32:54989 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:27990 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:54991 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:20992
993 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:47994 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:20995 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:47996 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:20997
jri78ec06a2016-03-31 18:19:40998 session_->connection()->CloseConnection(
999 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:201000
rch11565e02016-02-09 20:13:471001 SSLInfo ssl_info2;
1002 stream_->GetSSLInfo(&ssl_info2);
1003 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:201004}
1005
rchcd379012017-04-12 21:53:321006TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1007 SetRequest("GET", "/", DEFAULT_PRIORITY);
1008 Initialize();
1009
1010 request_.method = "GET";
1011 request_.url = GURL("https://www.example.org/");
1012
1013 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271014 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
rchcd379012017-04-12 21:53:321015 net_log_.bound(), callback_.callback()));
1016
1017 AlternativeService alternative_service;
1018 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1019 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1020 alternative_service);
1021
1022 session_->connection()->CloseConnection(
1023 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
1024
1025 AlternativeService alternative_service2;
1026 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1027 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1028 alternative_service2);
1029}
1030
zhongyica364fbb2015-12-12 03:39:121031TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1032 SetRequest("GET", "/", DEFAULT_PRIORITY);
1033 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371034 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361035 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371036 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361037 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1038 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1039 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371040 AddWrite(ConstructAckAndRstStreamPacket(3));
zhongyica364fbb2015-12-12 03:39:121041 Initialize();
1042
1043 request_.method = "GET";
rchcd379012017-04-12 21:53:321044 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121045
xunjieli5fafe142016-03-23 23:32:541046 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271047 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541048 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121049 EXPECT_EQ(OK,
1050 stream_->SendRequest(headers_, &response_, callback_.callback()));
1051
1052 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491053 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1055 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121056
rch1c5b74a2016-06-23 22:10:551057 QuicConnectionCloseFrame frame;
1058 frame.error_code = QUIC_PEER_GOING_AWAY;
1059 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121060
1061 NetErrorDetails details;
1062 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
1063 stream_->PopulateNetErrorDetails(&details);
1064 EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
1065}
1066
Ryan Hamiltone316e482017-08-17 02:48:531067TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
rch617e0652017-04-26 17:57:511068 // By default the test setup defaults handshake to be confirmed. Manually set
1069 // it to be not confirmed.
rch617e0652017-04-26 17:57:511070 crypto_client_stream_factory_.set_handshake_mode(
1071 MockCryptoClientStream::ZERO_RTT);
1072
zhongyica364fbb2015-12-12 03:39:121073 SetRequest("GET", "/", DEFAULT_PRIORITY);
1074 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371075 QuicStreamOffset header_stream_offset = 0;
fayang3bcb8b502016-12-07 21:44:371076 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361077 1, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1078 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1079 &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:121080 Initialize();
1081
1082 request_.method = "GET";
rchcd379012017-04-12 21:53:321083 request_.url = GURL("https://www.example.org/");
zhongyica364fbb2015-12-12 03:39:121084
xunjieli5fafe142016-03-23 23:32:541085 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271086 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541087 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121088 EXPECT_EQ(OK,
1089 stream_->SendRequest(headers_, &response_, callback_.callback()));
1090
1091 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491092 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011093 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1094 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121095
rch1c5b74a2016-06-23 22:10:551096 QuicConnectionCloseFrame frame;
1097 frame.error_code = QUIC_PEER_GOING_AWAY;
1098 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121099
1100 NetErrorDetails details;
zhongyica364fbb2015-12-12 03:39:121101 stream_->PopulateNetErrorDetails(&details);
Ryan Hamiltone316e482017-08-17 02:48:531102 EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:121103}
1104
rch11a114a2014-09-04 23:41:591105// Regression test for http://crbug.com/409871
1106TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1107 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451108 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371109 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361110 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371111 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361112 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1113 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1114 &header_stream_offset));
rch11a114a2014-09-04 23:41:591115 Initialize();
1116
1117 request_.method = "GET";
rchcd379012017-04-12 21:53:321118 request_.url = GURL("https://www.example.org/");
rch11a114a2014-09-04 23:41:591119
xunjieli5fafe142016-03-23 23:32:541120 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271121 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541122 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591123
rjshaded5ced072015-12-18 19:26:021124 EXPECT_EQ(OK,
1125 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591126
jri78ec06a2016-03-31 18:19:401127 session_->connection()->CloseConnection(
1128 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591129
1130 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101131
1132 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451133 // headers and payload.
1134 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1135 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101136 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591137}
1138
[email protected]1e960032013-12-20 19:00:201139TEST_P(QuicHttpStreamTest, SendPostRequest) {
1140 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451141 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371142 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361143 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371144 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361145 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1146 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1147 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371148 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, kUploadData));
wangyix6444ffe2017-04-25 17:49:491149 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]f702d572012-12-04 15:56:201150
1151 Initialize();
1152
danakjad1777e2016-04-16 00:56:421153 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191154 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:071155 kUploadData, strlen(kUploadData)));
rch97827ee2017-05-24 23:49:121156 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191157 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201158 request_.method = "POST";
rchcd379012017-04-12 21:53:321159 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121160 request_.upload_data_stream = upload_data_stream_.get();
tfarina42834112016-09-22 13:38:201161 ASSERT_THAT(request_.upload_data_stream->Init(CompletionCallback(),
1162 NetLogWithSource()),
1163 IsOk());
[email protected]f702d572012-12-04 15:56:201164
xunjieli5fafe142016-03-23 23:32:541165 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271166 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541167 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021168 EXPECT_EQ(OK,
1169 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201170
1171 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491172 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]f702d572012-12-04 15:56:201173
1174 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071175 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451176 size_t spdy_response_headers_frame_length;
1177 ProcessPacket(ConstructResponseHeadersPacket(
1178 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201179
rchfb47f712017-05-21 03:24:001180 // The headers have already arrived.
1181 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361182 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201183 EXPECT_EQ(200, response_.headers->response_code());
1184 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1185
1186 // Send the response body.
1187 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581188 ProcessPacket(ConstructServerDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:201189 // Since the body has already arrived, this should return immediately.
1190 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1191 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1192 callback_.callback()));
Ryan Hamilton2ef0a9c2017-07-25 03:18:291193 EXPECT_EQ(0,
1194 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1195 callback_.callback()));
1196
1197 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1198 EXPECT_TRUE(AtEof());
1199
1200 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1201 // headers and payload.
1202 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1203 strlen(kUploadData)),
1204 stream_->GetTotalSentBytes());
1205 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1206 strlen(kResponseBody)),
1207 stream_->GetTotalReceivedBytes());
1208}
1209
1210TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1211 SetRequest("POST", "/", DEFAULT_PRIORITY);
1212 size_t spdy_request_headers_frame_length;
1213 QuicStreamOffset header_stream_offset = 0;
1214 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
1215 AddWrite(InnerConstructRequestHeadersPacket(
1216 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1217 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1218 &header_stream_offset));
1219 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, kUploadData));
1220 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
1221
1222 Initialize();
1223
1224 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:191225 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
Ryan Hamilton2ef0a9c2017-07-25 03:18:291226 kUploadData, strlen(kUploadData)));
1227 upload_data_stream_ =
Jeremy Roman0579ed62017-08-29 15:56:191228 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
Ryan Hamilton2ef0a9c2017-07-25 03:18:291229 request_.method = "POST";
1230 request_.url = GURL("https://www.example.org/");
1231 request_.upload_data_stream = upload_data_stream_.get();
1232 ASSERT_THAT(request_.upload_data_stream->Init(CompletionCallback(),
1233 NetLogWithSource()),
1234 IsOk());
1235
1236 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271237 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
Ryan Hamilton2ef0a9c2017-07-25 03:18:291238 net_log_.bound(), callback_.callback()));
1239 EXPECT_EQ(OK,
1240 stream_->SendRequest(headers_, &response_, callback_.callback()));
1241
1242 // Ack both packets in the request.
1243 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
1244
1245 // Send the response headers (but not the body).
1246 SetResponse("200 OK", string());
1247 size_t spdy_response_headers_frame_length;
1248 ProcessPacket(ConstructResponseHeadersPacket(
1249 2, !kFin, &spdy_response_headers_frame_length));
1250
1251 // The headers have already arrived.
1252 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1253 ASSERT_TRUE(response_.headers.get());
1254 EXPECT_EQ(200, response_.headers->response_code());
1255 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1256
1257 // Send the response body.
1258 const char kResponseBody[] = "Hello world!";
1259 ProcessPacket(ConstructServerDataPacket(3, false, !kFin, 0, kResponseBody));
1260 // Since the body has already arrived, this should return immediately.
1261 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1262 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1263 callback_.callback()));
1264 ProcessPacket(ConstructServerDataPacket(4, false, kFin,
1265 arraysize(kResponseBody) - 1, ""));
1266 EXPECT_EQ(0,
1267 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1268 callback_.callback()));
[email protected]f702d572012-12-04 15:56:201269
1270 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1271 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101272
1273 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451274 // headers and payload.
1275 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1276 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101277 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451278 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1279 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101280 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201281}
1282
[email protected]1e960032013-12-20 19:00:201283TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1284 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471285 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451286 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371287 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361288 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371289 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361290 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1291 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1292 &header_stream_offset));
rjshaded5ced072015-12-18 19:26:021293 AddWrite(
fayang3bcb8b502016-12-07 21:44:371294 ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
1295 AddWrite(ConstructClientDataPacket(4, kIncludeVersion, kFin, chunk_size,
alyssar2adf3ac2016-05-03 17:12:581296 kUploadData));
wangyix6444ffe2017-04-25 17:49:491297 AddWrite(ConstructClientAckPacket(5, 3, 1, 1));
[email protected]c9e49a02013-02-26 05:56:471298 Initialize();
1299
Jeremy Roman0579ed62017-08-29 15:56:191300 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121301 auto* chunked_upload_stream =
1302 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1303 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471304
1305 request_.method = "POST";
rchcd379012017-04-12 21:53:321306 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121307 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071308 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201309 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]c9e49a02013-02-26 05:56:471310
xunjieli5fafe142016-03-23 23:32:541311 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271312 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541313 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021314 ASSERT_EQ(ERR_IO_PENDING,
1315 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471316
rch97827ee2017-05-24 23:49:121317 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471319
1320 // Ack both packets in the request.
wangyix6444ffe2017-04-25 17:49:491321 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]c9e49a02013-02-26 05:56:471322
1323 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071324 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451325 size_t spdy_response_headers_frame_length;
1326 ProcessPacket(ConstructResponseHeadersPacket(
1327 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471328
rchfb47f712017-05-21 03:24:001329 // The headers have already arrived.
1330 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]cadac622013-06-11 16:46:361331 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471332 EXPECT_EQ(200, response_.headers->response_code());
1333 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1334
1335 // Send the response body.
1336 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581337 ProcessPacket(ConstructServerDataPacket(
1338 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471339
1340 // Since the body has already arrived, this should return immediately.
1341 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1342 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1343 callback_.callback()));
1344
1345 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1346 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101347
1348 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451349 // headers and payload.
1350 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1351 strlen(kUploadData) * 2),
sclittle1edeeb22015-09-02 20:46:101352 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451353 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1354 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101355 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471356}
1357
[email protected]16ba7742014-08-22 00:57:251358TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1359 SetRequest("POST", "/", DEFAULT_PRIORITY);
1360 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451361 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371362 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361363 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371364 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361365 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1366 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1367 &header_stream_offset));
alyssar2adf3ac2016-05-03 17:12:581368 AddWrite(
fayang3bcb8b502016-12-07 21:44:371369 ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
1370 AddWrite(ConstructClientDataPacket(4, kIncludeVersion, kFin, chunk_size, ""));
wangyix6444ffe2017-04-25 17:49:491371 AddWrite(ConstructClientAckPacket(5, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251372 Initialize();
1373
Jeremy Roman0579ed62017-08-29 15:56:191374 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121375 auto* chunked_upload_stream =
1376 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1377 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251378
1379 request_.method = "POST";
rchcd379012017-04-12 21:53:321380 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121381 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071382 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201383 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251384
xunjieli5fafe142016-03-23 23:32:541385 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271386 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541387 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021388 ASSERT_EQ(ERR_IO_PENDING,
1389 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251390
rch97827ee2017-05-24 23:49:121391 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011392 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251393
wangyix6444ffe2017-04-25 17:49:491394 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251395
1396 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071397 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451398 size_t spdy_response_headers_frame_length;
1399 ProcessPacket(ConstructResponseHeadersPacket(
1400 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251401
rchfb47f712017-05-21 03:24:001402 // The headers have already arrived.
1403 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251404 ASSERT_TRUE(response_.headers.get());
1405 EXPECT_EQ(200, response_.headers->response_code());
1406 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1407
1408 // Send the response body.
1409 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581410 ProcessPacket(ConstructServerDataPacket(
1411 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251412
rchb27683c2015-07-29 23:53:501413 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251414 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1415 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1416 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251417 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1418 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101419
1420 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451421 // headers and payload.
1422 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1423 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101424 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451425 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1426 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101427 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251428}
1429
1430TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1431 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451432 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371433 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361434 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371435 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361436 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1437 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1438 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371439 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, 0, ""));
wangyix6444ffe2017-04-25 17:49:491440 AddWrite(ConstructClientAckPacket(4, 3, 1, 1));
[email protected]16ba7742014-08-22 00:57:251441 Initialize();
1442
Jeremy Roman0579ed62017-08-29 15:56:191443 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121444 auto* chunked_upload_stream =
1445 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
[email protected]16ba7742014-08-22 00:57:251446
1447 request_.method = "POST";
rchcd379012017-04-12 21:53:321448 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121449 request_.upload_data_stream = upload_data_stream_.get();
mmenkecbc2b712014-10-09 20:29:071450 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201451 TestCompletionCallback().callback(), NetLogWithSource()));
[email protected]16ba7742014-08-22 00:57:251452
xunjieli5fafe142016-03-23 23:32:541453 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271454 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541455 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021456 ASSERT_EQ(ERR_IO_PENDING,
1457 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251458
rch97827ee2017-05-24 23:49:121459 chunked_upload_stream->AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011460 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251461
wangyix6444ffe2017-04-25 17:49:491462 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
[email protected]16ba7742014-08-22 00:57:251463
1464 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071465 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451466 size_t spdy_response_headers_frame_length;
1467 ProcessPacket(ConstructResponseHeadersPacket(
1468 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251469
rchfb47f712017-05-21 03:24:001470 // The headers have already arrived.
1471 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
[email protected]16ba7742014-08-22 00:57:251472 ASSERT_TRUE(response_.headers.get());
1473 EXPECT_EQ(200, response_.headers->response_code());
1474 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1475
1476 // Send the response body.
1477 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581478 ProcessPacket(ConstructServerDataPacket(
1479 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251480
rchb27683c2015-07-29 23:53:501481 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251482 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1483 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1484 callback_.callback()));
1485
1486 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1487 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101488
1489 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451490 // headers and payload.
1491 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1492 stream_->GetTotalSentBytes());
1493 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1494 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101495 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251496}
1497
[email protected]1e960032013-12-20 19:00:201498TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1499 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451500 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371501 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361502 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371503 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361504 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin,
1505 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1506 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371507 AddWrite(ConstructAckAndRstStreamPacket(3));
[email protected]63534512012-12-23 18:49:001508 Initialize();
1509
1510 request_.method = "GET";
rchcd379012017-04-12 21:53:321511 request_.url = GURL("https://www.example.org/");
[email protected]63534512012-12-23 18:49:001512
xunjieli5fafe142016-03-23 23:32:541513 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271514 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541515 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021516 EXPECT_EQ(OK,
1517 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001518
1519 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491520 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
rchfb47f712017-05-21 03:24:001521 EXPECT_THAT(stream_->ReadResponseHeaders(
1522 base::Bind(&QuicHttpStreamTest::CloseStream,
1523 base::Unretained(this), stream_.get())),
robpercival214763f2016-07-01 23:27:011524 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001525
1526 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201527 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001528 // In the course of processing this packet, the QuicHttpStream close itself.
rchfb47f712017-05-21 03:24:001529 size_t response_size = 0;
rch1bcfddf22017-06-03 00:26:291530 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
[email protected]63534512012-12-23 18:49:001531
fdoray92e35a72016-06-10 15:54:551532 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501533
[email protected]63534512012-12-23 18:49:001534 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101535
1536 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451537 // headers and payload.
1538 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1539 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001540 // The stream was closed after receiving the headers.
1541 EXPECT_EQ(static_cast<int64_t>(response_size),
1542 stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001543}
1544
[email protected]1e960032013-12-20 19:00:201545TEST_P(QuicHttpStreamTest, Priority) {
1546 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451547 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371548 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361549 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371550 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361551 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, kFin, MEDIUM,
fayang3bcb8b502016-12-07 21:44:371552 &spdy_request_headers_frame_length, &header_stream_offset));
[email protected]24e5bc52013-09-18 15:36:581553 Initialize();
1554
1555 request_.method = "GET";
rchcd379012017-04-12 21:53:321556 request_.url = GURL("https://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581557
Steven Valdezb4ff0412018-01-18 22:39:271558 EXPECT_EQ(OK,
1559 stream_->InitializeStream(&request_, true, MEDIUM, net_log_.bound(),
1560 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581561
1562 // Check that priority is highest.
rch08e198572017-05-09 16:56:551563 QuicChromiumClientStream::Handle* reliable_stream =
rch12fef552016-01-15 16:26:311564 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
[email protected]24e5bc52013-09-18 15:36:581565 DCHECK(reliable_stream);
fayanga64c1a92016-02-13 01:55:581566 DCHECK_EQ(kV3HighestPriority, reliable_stream->priority());
[email protected]24e5bc52013-09-18 15:36:581567
rjshaded5ced072015-12-18 19:26:021568 EXPECT_EQ(OK,
1569 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581570
1571 // Check that priority has now dropped back to MEDIUM.
ianswett0888cff2015-11-24 17:42:161572 DCHECK_EQ(MEDIUM,
fayanga64c1a92016-02-13 01:55:581573 ConvertQuicPriorityToRequestPriority(reliable_stream->priority()));
[email protected]24e5bc52013-09-18 15:36:581574
1575 // Ack the request.
wangyix6444ffe2017-04-25 17:49:491576 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
robpercival214763f2016-07-01 23:27:011577 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1578 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581579
1580 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201581 SetResponse("404 OK", "hello world!");
rchfb47f712017-05-21 03:24:001582 size_t response_size = 0;
1583 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
[email protected]24e5bc52013-09-18 15:36:581584
rchfb47f712017-05-21 03:24:001585 EXPECT_EQ(OK, callback_.WaitForResult());
rchb27683c2015-07-29 23:53:501586
[email protected]24e5bc52013-09-18 15:36:581587 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101588
1589 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451590 // headers and payload.
1591 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1592 stream_->GetTotalSentBytes());
rchfb47f712017-05-21 03:24:001593 EXPECT_EQ(static_cast<int64_t>(response_size),
1594 stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581595}
1596
xunjieli8dff50b2016-07-22 14:19:061597TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1598 SetRequest("POST", "/", DEFAULT_PRIORITY);
1599 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371600 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361601 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371602 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361603 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1604 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1605 &header_stream_offset));
xunjieli8dff50b2016-07-22 14:19:061606 AddWrite(
fayang3bcb8b502016-12-07 21:44:371607 ConstructClientDataPacket(3, kIncludeVersion, !kFin, 0, kUploadData));
xunjieli8dff50b2016-07-22 14:19:061608 // Second data write will result in a synchronous failure which will close
1609 // the session.
1610 AddWrite(SYNCHRONOUS, ERR_FAILED);
1611 Initialize();
1612
Jeremy Roman0579ed62017-08-29 15:56:191613 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121614 auto* chunked_upload_stream =
1615 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
xunjieli8dff50b2016-07-22 14:19:061616
1617 request_.method = "POST";
rchcd379012017-04-12 21:53:321618 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121619 request_.upload_data_stream = upload_data_stream_.get();
xunjieli8dff50b2016-07-22 14:19:061620 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201621 TestCompletionCallback().callback(), NetLogWithSource()));
xunjieli8dff50b2016-07-22 14:19:061622
1623 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121624 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
xunjieli8dff50b2016-07-22 14:19:061625 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271626 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli8dff50b2016-07-22 14:19:061627 net_log_.bound(), callback_.callback()));
1628 QuicHttpStream* stream = stream_.get();
1629 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1630 // SendRequest() completes asynchronously after the final chunk is added.
1631 ASSERT_EQ(ERR_IO_PENDING,
1632 stream->SendRequest(headers_, &response_, callback_.callback()));
rch97827ee2017-05-24 23:49:121633 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
xunjieli8dff50b2016-07-22 14:19:061634 int rv = callback_.WaitForResult();
1635 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, rv);
1636}
1637
rtenneti15656ae2016-01-23 03:05:031638TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1639 SetRequest("POST", "/", DEFAULT_PRIORITY);
fayang3bcb8b502016-12-07 21:44:371640 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361641 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031642 AddWrite(SYNCHRONOUS, ERR_FAILED);
1643 Initialize();
1644
Jeremy Roman0579ed62017-08-29 15:56:191645 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rtenneti15656ae2016-01-23 03:05:031646
1647 request_.method = "POST";
rchcd379012017-04-12 21:53:321648 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121649 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031650 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201651 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031652
xunjieli5fafe142016-03-23 23:32:541653 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271654 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541655 net_log_.bound(), callback_.callback()));
rtenneti15656ae2016-01-23 03:05:031656 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1657 stream_->SendRequest(headers_, &response_, callback_.callback()));
mmenkeffff3642017-06-15 17:37:241658
1659 EXPECT_LE(0, stream_->GetTotalSentBytes());
1660 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rtenneti15656ae2016-01-23 03:05:031661}
1662
1663TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1664 SetRequest("POST", "/", DEFAULT_PRIORITY);
1665 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:371666 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361667 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:371668 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:361669 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
1670 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1671 &header_stream_offset));
rtenneti15656ae2016-01-23 03:05:031672 AddWrite(SYNCHRONOUS, ERR_FAILED);
1673 Initialize();
1674
Jeremy Roman0579ed62017-08-29 15:56:191675 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
rch97827ee2017-05-24 23:49:121676 auto* chunked_upload_stream =
1677 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
rtenneti15656ae2016-01-23 03:05:031678 size_t chunk_size = strlen(kUploadData);
rch97827ee2017-05-24 23:49:121679 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
rtenneti15656ae2016-01-23 03:05:031680
1681 request_.method = "POST";
rchcd379012017-04-12 21:53:321682 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:121683 request_.upload_data_stream = upload_data_stream_.get();
rtenneti15656ae2016-01-23 03:05:031684 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:201685 TestCompletionCallback().callback(), NetLogWithSource()));
rtenneti15656ae2016-01-23 03:05:031686
xunjieli5fafe142016-03-23 23:32:541687 ASSERT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271688 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541689 net_log_.bound(), callback_.callback()));
rtenneti15656ae2016-01-23 03:05:031690 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1691 stream_->SendRequest(headers_, &response_, callback_.callback()));
1692}
1693
ckrasic3865ee0f2016-02-29 22:04:561694TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1695 SetRequest("GET", "/", DEFAULT_PRIORITY);
1696 Initialize();
1697
1698 // Initialize the first stream, for receiving the promise on.
1699 request_.method = "GET";
rchcd379012017-04-12 21:53:321700 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561701
xunjieli5fafe142016-03-23 23:32:541702 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271703 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541704 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561705
1706 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1707 // packet, but does it matter?
1708 ReceivePromise(promise_id_);
1709 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1710
1711 request_.url = GURL(promise_url_);
1712
1713 // Make the second stream that will exercise the first step of the
1714 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271715 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1716 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1717 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561718
1719 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251720 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561721 size_t spdy_response_headers_frame_length;
1722 ProcessPacket(InnerConstructResponseHeadersPacket(
1723 1, promise_id_, false, &spdy_response_headers_frame_length));
1724
1725 // Receive the promised response body.
1726 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581727 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1728 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561729
1730 // Now sending a matching request will have successful rendezvous
1731 // with the promised stream.
1732 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1733 callback_.callback()));
1734
1735 EXPECT_EQ(
1736 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1737 ->id(),
1738 promise_id_);
1739
1740 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011741 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1742 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561743
1744 // As will be the body.
1745 EXPECT_EQ(
1746 static_cast<int>(strlen(kResponseBody)),
1747 promised_stream_->ReadResponseBody(
1748 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1749 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1750 EXPECT_TRUE(AtEof());
1751
1752 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1753 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1754 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1755 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1756 strlen(kResponseBody)),
1757 promised_stream_->GetTotalReceivedBytes());
1758}
1759
1760TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
1761 SetRequest("GET", "/", DEFAULT_PRIORITY);
1762 Initialize();
1763
1764 // Initialize the first stream, for receiving the promise on.
1765 request_.method = "GET";
rchcd379012017-04-12 21:53:321766 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561767
xunjieli5fafe142016-03-23 23:32:541768 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271769 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541770 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561771
1772 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1773 // packet, but does it matter?
1774 ReceivePromise(promise_id_);
1775 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1776
1777 request_.url = GURL(promise_url_);
1778
1779 // Make the second stream that will exercise the first step of the
1780 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271781 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1782 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1783 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561784
1785 // Now sending a matching request will rendezvous with the promised
1786 // stream, but pending secondary validation.
1787 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1788 headers_, &response_, callback_.callback()));
1789
1790 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251791 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561792 size_t spdy_response_headers_frame_length;
1793 ProcessPacket(InnerConstructResponseHeadersPacket(
1794 1, promise_id_, false, &spdy_response_headers_frame_length));
1795
1796 // Receive the promised response body.
1797 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581798 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1799 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561800
fdoray92e35a72016-06-10 15:54:551801 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561802
1803 // Rendezvous should have succeeded now, so the promised stream
1804 // should point at our push stream, and we should be able read
1805 // headers and data from it.
robpercival214763f2016-07-01 23:27:011806 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:561807
1808 EXPECT_EQ(
1809 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1810 ->id(),
1811 promise_id_);
1812
robpercival214763f2016-07-01 23:27:011813 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1814 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561815
1816 EXPECT_EQ(
1817 static_cast<int>(strlen(kResponseBody)),
1818 promised_stream_->ReadResponseBody(
1819 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1820
1821 // Callback should return
1822 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1823 EXPECT_TRUE(AtEof());
1824
1825 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1826 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1827 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1828 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1829 strlen(kResponseBody)),
1830 promised_stream_->GetTotalReceivedBytes());
1831}
1832
ckrasic2c63f9b2016-08-16 23:54:071833// Verify fix for crbug.com/637349
1834TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
1835 SetRequest("GET", "/", DEFAULT_PRIORITY);
1836 Initialize();
1837
1838 // Initialize the first stream, for receiving the promise on.
1839 request_.method = "GET";
rchcd379012017-04-12 21:53:321840 request_.url = GURL("https://www.example.org/");
ckrasic2c63f9b2016-08-16 23:54:071841
1842 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271843 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
ckrasic2c63f9b2016-08-16 23:54:071844 net_log_.bound(), callback_.callback()));
1845
1846 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1847 // packet, but does it matter?
1848 ReceivePromise(promise_id_);
1849 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1850
1851 request_.url = GURL(promise_url_);
1852
1853 // Make the second stream that will exercise the first step of the
1854 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271855 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1856 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1857 callback_.callback()));
ckrasic2c63f9b2016-08-16 23:54:071858
1859 // Now sending a matching request will rendezvous with the promised
1860 // stream, but pending secondary validation.
1861 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1862 headers_, &response_, callback_.callback()));
1863
1864 base::RunLoop().RunUntilIdle();
1865
1866 // Cause of FinalValidation() crash as per bug.
1867 promised_stream_.reset();
1868
1869 // Receive the promised response headers.
1870 response_headers_ = promised_response_.Clone();
1871 size_t spdy_response_headers_frame_length;
1872 ProcessPacket(InnerConstructResponseHeadersPacket(
1873 1, promise_id_, false, &spdy_response_headers_frame_length));
1874}
1875
ckrasic3865ee0f2016-02-29 22:04:561876TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
1877 SetRequest("GET", "/", DEFAULT_PRIORITY);
1878 Initialize();
1879
1880 // Initialize the first stream, for receiving the promise on.
1881 request_.method = "GET";
rchcd379012017-04-12 21:53:321882 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561883
xunjieli5fafe142016-03-23 23:32:541884 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271885 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541886 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561887
1888 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1889 // packet, but does it matter?
1890
1891 push_promise_[":authority"] = "mail.example.org";
Yixin Wang81c11182018-02-05 20:09:571892 promise_url_ = SpdyUtils::GetPromisedUrlFromHeaderBlock(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:561893
1894 ReceivePromise(promise_id_);
1895 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1896
1897 request_.url = GURL(promise_url_);
1898
1899 // Make the second stream that will exercise the first step of the
1900 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271901 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1902 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1903 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561904
1905 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251906 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561907 size_t spdy_response_headers_frame_length;
1908 ProcessPacket(InnerConstructResponseHeadersPacket(
1909 1, promise_id_, false, &spdy_response_headers_frame_length));
1910
1911 // Receive the promised response body.
1912 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581913 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1914 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561915
1916 // Now sending a matching request will have successful rendezvous
1917 // with the promised stream.
1918 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1919 callback_.callback()));
1920
1921 EXPECT_EQ(
1922 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1923 ->id(),
1924 promise_id_);
1925
1926 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011927 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1928 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561929
1930 // As will be the body.
1931 EXPECT_EQ(
1932 static_cast<int>(strlen(kResponseBody)),
1933 promised_stream_->ReadResponseBody(
1934 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1935 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1936 EXPECT_TRUE(AtEof());
1937
1938 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1939 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1940 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1941 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1942 strlen(kResponseBody)),
1943 promised_stream_->GetTotalReceivedBytes());
1944}
1945
1946TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
1947 SetRequest("GET", "/", DEFAULT_PRIORITY);
1948 Initialize();
1949
1950 // Initialize the first stream, for receiving the promise on.
1951 request_.method = "GET";
rchcd379012017-04-12 21:53:321952 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561953
xunjieli5fafe142016-03-23 23:32:541954 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271955 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541956 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561957
1958 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1959 // packet, but does it matter?
1960 push_promise_[":authority"] = "www.notexample.org";
Yixin Wang81c11182018-02-05 20:09:571961 promise_url_ = SpdyUtils::GetPromisedUrlFromHeaderBlock(push_promise_);
ckrasic3865ee0f2016-02-29 22:04:561962
1963 ReceivePromise(promise_id_);
1964 // The promise will have been rejected because the cert doesn't
1965 // match.
1966 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
1967}
1968
1969TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
1970 SetRequest("GET", "/", DEFAULT_PRIORITY);
1971 Initialize();
1972
1973 // Initialize the first stream, for receiving the promise on.
1974 request_.method = "GET";
rchcd379012017-04-12 21:53:321975 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:561976
xunjieli5fafe142016-03-23 23:32:541977 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:271978 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:541979 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561980
1981 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:561982
1983 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1984 // packet, but does it matter?
1985 ReceivePromise(promise_id_);
1986 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1987
1988 request_.url = GURL(promise_url_);
1989
1990 // Make the second stream that will exercise the first step of the
1991 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:271992 EXPECT_EQ(OK, promised_stream_->InitializeStream(
1993 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
1994 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561995
1996 headers_.SetHeader("accept-encoding", "gzip");
1997
1998 // Now sending a matching request will rendezvous with the promised
1999 // stream, but pending secondary validation.
2000 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2001 headers_, &response_, callback_.callback()));
2002
2003 // Receive the promised response headers.
2004 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252005 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562006 size_t spdy_response_headers_frame_length;
2007 ProcessPacket(InnerConstructResponseHeadersPacket(
2008 1, promise_id_, false, &spdy_response_headers_frame_length));
2009
2010 // Receive the promised response body.
2011 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:582012 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
2013 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:562014
fdoray92e35a72016-06-10 15:54:552015 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562016
2017 // Rendezvous should have succeeded now, so the promised stream
2018 // should point at our push stream, and we should be able read
2019 // headers and data from it.
robpercival214763f2016-07-01 23:27:012020 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562021
2022 EXPECT_EQ(
2023 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2024 ->id(),
2025 promise_id_);
2026
robpercival214763f2016-07-01 23:27:012027 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2028 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562029
2030 EXPECT_EQ(
2031 static_cast<int>(strlen(kResponseBody)),
2032 promised_stream_->ReadResponseBody(
2033 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2034
2035 // Callback should return
2036 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2037 EXPECT_TRUE(AtEof());
2038
2039 EXPECT_EQ(0, stream_->GetTotalSentBytes());
2040 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2041 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
2042 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
2043 strlen(kResponseBody)),
2044 promised_stream_->GetTotalReceivedBytes());
2045}
2046
2047TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
2048 SetRequest("GET", "/", DEFAULT_PRIORITY);
2049 request_headers_[":scheme"] = "https";
2050 request_headers_[":path"] = "/bar";
2051 request_headers_["accept-encoding"] = "sdch";
2052
2053 size_t spdy_request_header_frame_length;
fayang3bcb8b502016-12-07 21:44:372054 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362055 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:572056
2057 QuicPacketNumber client_packet_number = 2;
2058 if (client_headers_include_h2_stream_dependency_ &&
2059 version_ > QUIC_VERSION_42) {
2060 AddWrite(ConstructClientPriorityPacket(
2061 client_packet_number++, kIncludeVersion, promise_id_, 0,
2062 DEFAULT_PRIORITY, &header_stream_offset));
2063 }
2064 AddWrite(ConstructClientRstStreamVaryMismatchPacket(client_packet_number++));
ckrasic3865ee0f2016-02-29 22:04:562065 AddWrite(InnerConstructRequestHeadersPacket(
Yixin Wangb470bc882018-02-15 18:43:572066 client_packet_number++, stream_id_ + 2, !kIncludeVersion, kFin,
2067 DEFAULT_PRIORITY, promise_id_, &spdy_request_header_frame_length,
2068 &header_stream_offset));
2069 AddWrite(ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
2070 AddWrite(ConstructClientRstStreamCancelledPacket(client_packet_number++));
2071
ckrasic3865ee0f2016-02-29 22:04:562072 Initialize();
2073
2074 // Initialize the first stream, for receiving the promise on.
2075 request_.method = "GET";
rchcd379012017-04-12 21:53:322076 request_.url = GURL("https://www.example.org/");
ckrasic3865ee0f2016-02-29 22:04:562077
xunjieli5fafe142016-03-23 23:32:542078 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272079 stream_->InitializeStream(&request_, true, DEFAULT_PRIORITY,
xunjieli5fafe142016-03-23 23:32:542080 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562081
2082 push_promise_["accept-encoding"] = "gzip";
ckrasic3865ee0f2016-02-29 22:04:562083
2084 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
2085 // packet, but does it matter?
2086 ReceivePromise(promise_id_);
2087 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
2088
2089 request_.url = GURL(promise_url_);
2090
2091 // Make the second stream that will exercise the first step of the
2092 // server push rendezvous mechanism.
Steven Valdezb4ff0412018-01-18 22:39:272093 EXPECT_EQ(OK, promised_stream_->InitializeStream(
2094 &request_, true, DEFAULT_PRIORITY, net_log_.bound(),
2095 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:562096
2097 headers_.SetHeader("accept-encoding", "sdch");
2098
2099 // Now sending a matching request will rendezvous with the promised
2100 // stream, but pending secondary validation.
2101 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
2102 headers_, &response_, callback_.callback()));
2103
2104 // Receive the promised response headers.
2105 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:252106 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:562107 size_t spdy_response_headers_frame_length;
2108 ProcessPacket(InnerConstructResponseHeadersPacket(
2109 1, promise_id_, false, &spdy_response_headers_frame_length));
2110
fdoray92e35a72016-06-10 15:54:552111 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562112
2113 // Rendezvous should have failed due to vary mismatch, so the
2114 // promised stream should have been aborted, and instead we have a
2115 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:012116 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:562117
2118 // Not a server-initiated stream.
2119 EXPECT_NE(
2120 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2121 ->id(),
2122 promise_id_);
2123
2124 // Instead, a new client-initiated stream.
2125 EXPECT_EQ(
2126 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
2127 ->id(),
2128 stream_id_ + 2);
2129
2130 // After rendezvous failure, the push stream has been cancelled.
2131 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
2132
2133 // The rest of the test verifies that the retried as
2134 // client-initiated version of |promised_stream_| works as intended.
2135
2136 // Ack the request.
wangyix6444ffe2017-04-25 17:49:492137 ProcessPacket(ConstructServerAckPacket(2, 0, 0, 0));
ckrasic3865ee0f2016-02-29 22:04:562138
bnc614a92d32016-04-04 13:56:072139 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:562140 size_t spdy_response_header_frame_length;
2141 ProcessPacket(InnerConstructResponseHeadersPacket(
2142 3, stream_id_ + 2, kFin, &spdy_response_header_frame_length));
2143
fdoray92e35a72016-06-10 15:54:552144 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:562145
robpercival214763f2016-07-01 23:27:012146 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
2147 IsOk());
ckrasic3865ee0f2016-02-29 22:04:562148 ASSERT_TRUE(response_.headers.get());
2149 EXPECT_EQ(404, response_.headers->response_code());
2150 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
2151 EXPECT_FALSE(response_.response_time.is_null());
2152 EXPECT_FALSE(response_.request_time.is_null());
2153
2154 // There is no body, so this should return immediately.
2155 EXPECT_EQ(
2156 0, promised_stream_->ReadResponseBody(
2157 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
2158 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
2159
2160 stream_->Close(true);
2161
2162 EXPECT_TRUE(AtEof());
2163
2164 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
2165 // headers and payload.
2166 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
2167 promised_stream_->GetTotalSentBytes());
2168 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
2169 promised_stream_->GetTotalReceivedBytes());
2170}
2171
maksim.sisov84e20c92016-06-23 08:49:342172TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2173 SetRequest("POST", "/", DEFAULT_PRIORITY);
2174 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:372175 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362176 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372177 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:362178 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
2179 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2180 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372181 AddWrite(ConstructClientRstStreamErrorPacket(3, kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342182
2183 Initialize();
2184
Jeremy Roman0579ed62017-08-29 15:56:192185 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342186 ReadErrorUploadDataStream::FailureMode::SYNC);
2187 request_.method = "POST";
rchcd379012017-04-12 21:53:322188 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122189 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342190 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202191 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342192
2193 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272194 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342195 net_log_.bound(), callback_.callback()));
2196
2197 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012198 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342199
2200 EXPECT_TRUE(AtEof());
2201
2202 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2203 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2204 stream_->GetTotalSentBytes());
2205 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2206}
2207
2208TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2209 SetRequest("POST", "/", DEFAULT_PRIORITY);
2210 size_t spdy_request_headers_frame_length;
fayang3bcb8b502016-12-07 21:44:372211 QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362212 AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372213 AddWrite(InnerConstructRequestHeadersPacket(
ckrasicbf2f59c2017-05-04 23:54:362214 2, GetNthClientInitiatedStreamId(0), kIncludeVersion, !kFin,
2215 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2216 &header_stream_offset));
fayang3bcb8b502016-12-07 21:44:372217 AddWrite(ConstructClientRstStreamErrorPacket(3, !kIncludeVersion));
maksim.sisov84e20c92016-06-23 08:49:342218
2219 Initialize();
2220
Jeremy Roman0579ed62017-08-29 15:56:192221 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
maksim.sisov84e20c92016-06-23 08:49:342222 ReadErrorUploadDataStream::FailureMode::ASYNC);
2223 request_.method = "POST";
rchcd379012017-04-12 21:53:322224 request_.url = GURL("https://www.example.org/");
rch97827ee2017-05-24 23:49:122225 request_.upload_data_stream = upload_data_stream_.get();
maksim.sisov84e20c92016-06-23 08:49:342226 ASSERT_EQ(OK, request_.upload_data_stream->Init(
tfarina42834112016-09-22 13:38:202227 TestCompletionCallback().callback(), NetLogWithSource()));
maksim.sisov84e20c92016-06-23 08:49:342228
2229 EXPECT_EQ(OK,
Steven Valdezb4ff0412018-01-18 22:39:272230 stream_->InitializeStream(&request_, false, DEFAULT_PRIORITY,
maksim.sisov84e20c92016-06-23 08:49:342231 net_log_.bound(), callback_.callback()));
2232
2233 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2234
wangyix6444ffe2017-04-25 17:49:492235 ProcessPacket(ConstructServerAckPacket(1, 0, 0, 0));
maksim.sisov84e20c92016-06-23 08:49:342236 SetResponse("200 OK", string());
2237
robpercival214763f2016-07-01 23:27:012238 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2239 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342240
2241 EXPECT_TRUE(AtEof());
2242
2243 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2244 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2245 stream_->GetTotalSentBytes());
2246 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2247}
2248
[email protected]f702d572012-12-04 15:56:202249} // namespace test
[email protected]f702d572012-12-04 15:56:202250} // namespace net