1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_http_stream.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10 #include <utility>
11
12 #include "base/functional/bind.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/run_loop.h"
16 #include "base/strings/strcat.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/task/single_thread_task_runner.h"
19 #include "base/test/metrics/histogram_tester.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/time/default_tick_clock.h"
22 #include "base/time/time.h"
23 #include "net/base/chunked_upload_data_stream.h"
24 #include "net/base/elements_upload_data_stream.h"
25 #include "net/base/features.h"
26 #include "net/base/load_flags.h"
27 #include "net/base/load_timing_info.h"
28 #include "net/base/load_timing_info_test_util.h"
29 #include "net/base/net_errors.h"
30 #include "net/base/test_completion_callback.h"
31 #include "net/base/upload_bytes_element_reader.h"
32 #include "net/dns/public/host_resolver_results.h"
33 #include "net/dns/public/secure_dns_policy.h"
34 #include "net/http/http_response_headers.h"
35 #include "net/http/transport_security_state.h"
36 #include "net/log/net_log.h"
37 #include "net/log/net_log_event_type.h"
38 #include "net/log/test_net_log.h"
39 #include "net/log/test_net_log_util.h"
40 #include "net/quic/address_utils.h"
41 #include "net/quic/crypto/proof_verifier_chromium.h"
42 #include "net/quic/mock_crypto_client_stream_factory.h"
43 #include "net/quic/quic_chromium_alarm_factory.h"
44 #include "net/quic/quic_chromium_connection_helper.h"
45 #include "net/quic/quic_chromium_packet_reader.h"
46 #include "net/quic/quic_chromium_packet_writer.h"
47 #include "net/quic/quic_context.h"
48 #include "net/quic/quic_crypto_client_config_handle.h"
49 #include "net/quic/quic_http_utils.h"
50 #include "net/quic/quic_server_info.h"
51 #include "net/quic/quic_stream_factory.h"
52 #include "net/quic/quic_test_packet_maker.h"
53 #include "net/quic/quic_test_packet_printer.h"
54 #include "net/quic/test_quic_crypto_client_config_handle.h"
55 #include "net/quic/test_task_runner.h"
56 #include "net/socket/socket_performance_watcher.h"
57 #include "net/socket/socket_test_util.h"
58 #include "net/spdy/spdy_http_utils.h"
59 #include "net/ssl/ssl_config_service_defaults.h"
60 #include "net/test/cert_test_util.h"
61 #include "net/test/gtest_util.h"
62 #include "net/test/test_data_directory.h"
63 #include "net/test/test_with_task_environment.h"
64 #include "net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.h"
65 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h"
66 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
67 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
68 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
69 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
70 #include "net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.h"
71 #include "net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.h"
72 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
73 #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
74 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
75 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_connection_id_generator.h"
76 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
77 #include "net/third_party/quiche/src/quiche/quic/test_tools/qpack/qpack_test_utils.h"
78 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
79 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
80 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
81 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
82 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
83 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
84 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
85 #include "testing/gmock/include/gmock/gmock.h"
86 #include "testing/gtest/include/gtest/gtest.h"
87 #include "url/scheme_host_port.h"
88 #include "url/url_constants.h"
89
90 using std::string;
91 using testing::_;
92 using testing::AnyNumber;
93 using testing::Return;
94
95 namespace net::test {
96 namespace {
97
98 const char kUploadData[] = "Really nifty data!";
99 const char kDefaultServerHostName[] = "www.example.org";
100 const uint16_t kDefaultServerPort = 443;
101
102 struct TestParams {
103 quic::ParsedQuicVersion version;
104 bool priority_header_enabled;
105 };
106
107 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)108 std::string PrintToString(const TestParams& p) {
109 return base::StrCat({ParsedQuicVersionToString(p.version), "_",
110 p.priority_header_enabled ? "PriorityHeaderEnabled"
111 : "PriorityHeaderDisabled"});
112 }
113
GetTestParams()114 std::vector<TestParams> GetTestParams() {
115 std::vector<TestParams> params;
116 quic::ParsedQuicVersionVector all_supported_versions =
117 AllSupportedQuicVersions();
118 for (const auto& version : all_supported_versions) {
119 params.push_back(TestParams{version, true});
120 params.push_back(TestParams{version, false});
121 }
122 return params;
123 }
124
125 // Returns true if |params| is a dict, has an entry with key "headers", that
126 // entry is a list of strings, which when interpreted as colon-separated
127 // key-value pairs has exactly one entry with |key| and that entry has value
128 // |expected_value|.
CheckHeader(const base::Value::Dict & params,base::StringPiece key,base::StringPiece expected_value)129 bool CheckHeader(const base::Value::Dict& params,
130 base::StringPiece key,
131 base::StringPiece expected_value) {
132 const base::Value::List* headers = params.FindList("headers");
133 if (!headers) {
134 return false;
135 }
136
137 std::string header_prefix = base::StrCat({key, ": "});
138 std::string expected_header = base::StrCat({header_prefix, expected_value});
139
140 bool header_found = false;
141 for (const auto& header_value : *headers) {
142 const std::string* header = header_value.GetIfString();
143 if (!header) {
144 return false;
145 }
146 if (header->starts_with(header_prefix)) {
147 if (header_found) {
148 return false;
149 }
150 if (*header != expected_header) {
151 return false;
152 }
153 header_found = true;
154 }
155 }
156 return header_found;
157 }
158
159 class TestQuicConnection : public quic::QuicConnection {
160 public:
TestQuicConnection(const quic::ParsedQuicVersionVector & versions,quic::QuicConnectionId connection_id,IPEndPoint address,QuicChromiumConnectionHelper * helper,QuicChromiumAlarmFactory * alarm_factory,quic::QuicPacketWriter * writer,quic::ConnectionIdGeneratorInterface & generator)161 TestQuicConnection(const quic::ParsedQuicVersionVector& versions,
162 quic::QuicConnectionId connection_id,
163 IPEndPoint address,
164 QuicChromiumConnectionHelper* helper,
165 QuicChromiumAlarmFactory* alarm_factory,
166 quic::QuicPacketWriter* writer,
167 quic::ConnectionIdGeneratorInterface& generator)
168 : quic::QuicConnection(connection_id,
169 quic::QuicSocketAddress(),
170 ToQuicSocketAddress(address),
171 helper,
172 alarm_factory,
173 writer,
174 true /* owns_writer */,
175 quic::Perspective::IS_CLIENT,
176 versions,
177 generator) {}
178
SetSendAlgorithm(quic::SendAlgorithmInterface * send_algorithm)179 void SetSendAlgorithm(quic::SendAlgorithmInterface* send_algorithm) {
180 quic::test::QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
181 }
182 };
183
184 // UploadDataStream that always returns errors on data read.
185 class ReadErrorUploadDataStream : public UploadDataStream {
186 public:
187 enum class FailureMode { SYNC, ASYNC };
188
ReadErrorUploadDataStream(FailureMode mode)189 explicit ReadErrorUploadDataStream(FailureMode mode)
190 : UploadDataStream(true, 0), async_(mode) {}
191
192 ReadErrorUploadDataStream(const ReadErrorUploadDataStream&) = delete;
193 ReadErrorUploadDataStream& operator=(const ReadErrorUploadDataStream&) =
194 delete;
195
196 ~ReadErrorUploadDataStream() override = default;
197
198 private:
CompleteRead()199 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
200
201 // UploadDataStream implementation:
InitInternal(const NetLogWithSource & net_log)202 int InitInternal(const NetLogWithSource& net_log) override { return OK; }
203
ReadInternal(IOBuffer * buf,int buf_len)204 int ReadInternal(IOBuffer* buf, int buf_len) override {
205 if (async_ == FailureMode::ASYNC) {
206 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
207 FROM_HERE, base::BindOnce(&ReadErrorUploadDataStream::CompleteRead,
208 weak_factory_.GetWeakPtr()));
209 return ERR_IO_PENDING;
210 }
211 return ERR_FAILED;
212 }
213
ResetInternal()214 void ResetInternal() override {}
215
216 const FailureMode async_;
217
218 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_{this};
219 };
220
221 // A helper class that will delete |stream| when the callback is invoked.
222 class DeleteStreamCallback : public TestCompletionCallbackBase {
223 public:
DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)224 explicit DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
225 : stream_(std::move(stream)) {}
226
callback()227 CompletionOnceCallback callback() {
228 return base::BindOnce(&DeleteStreamCallback::DeleteStream,
229 base::Unretained(this));
230 }
231
232 private:
DeleteStream(int result)233 void DeleteStream(int result) {
234 stream_.reset();
235 SetResult(result);
236 }
237
238 std::unique_ptr<QuicHttpStream> stream_;
239 };
240
241 } // namespace
242
243 class QuicHttpStreamPeer {
244 public:
GetQuicChromiumClientStream(QuicHttpStream * stream)245 static QuicChromiumClientStream::Handle* GetQuicChromiumClientStream(
246 QuicHttpStream* stream) {
247 return stream->stream_.get();
248 }
249 };
250
251 class QuicHttpStreamTest : public ::testing::TestWithParam<TestParams>,
252 public WithTaskEnvironment {
253 public:
CloseStream(QuicHttpStream * stream,int)254 void CloseStream(QuicHttpStream* stream, int /*rv*/) { stream->Close(false); }
255
256 protected:
257 static const bool kFin = true;
258
259 // Holds a packet to be written to the wire, and the IO mode that should
260 // be used by the mock socket when performing the write.
261 struct PacketToWrite {
PacketToWritenet::test::QuicHttpStreamTest::PacketToWrite262 PacketToWrite(IoMode mode, std::unique_ptr<quic::QuicReceivedPacket> packet)
263 : mode(mode), packet(std::move(packet)) {}
PacketToWritenet::test::QuicHttpStreamTest::PacketToWrite264 PacketToWrite(IoMode mode, int rv) : mode(mode), rv(rv) {}
265
266 IoMode mode;
267 int rv;
268 std::unique_ptr<quic::QuicReceivedPacket> packet;
269 };
270
QuicHttpStreamTest()271 QuicHttpStreamTest()
272 : version_(GetParam().version),
273 crypto_config_(
274 quic::test::crypto_test_utils::ProofVerifierForTesting()),
275 read_buffer_(base::MakeRefCounted<IOBufferWithSize>(4096)),
276 stream_id_(GetNthClientInitiatedBidirectionalStreamId(0)),
277 connection_id_(quic::test::TestConnectionId(2)),
278 client_maker_(version_,
279 connection_id_,
280 &clock_,
281 kDefaultServerHostName,
282 quic::Perspective::IS_CLIENT,
283 /*client_priority_uses_incremental=*/true,
284 /*use_priority_header=*/true),
285 server_maker_(version_,
286 connection_id_,
287 &clock_,
288 kDefaultServerHostName,
289 quic::Perspective::IS_SERVER,
290 /*client_priority_uses_incremental=*/false,
291 /*use_priority_header=*/false),
292 printer_(version_) {
293 if (GetParam().priority_header_enabled) {
294 feature_list_.InitAndEnableFeature(net::features::kPriorityHeader);
295 } else {
296 feature_list_.InitAndDisableFeature(net::features::kPriorityHeader);
297 }
298 FLAGS_quic_enable_http3_grease_randomness = false;
299 quic::QuicEnableVersion(version_);
300 IPAddress ip(192, 0, 2, 33);
301 peer_addr_ = IPEndPoint(ip, 443);
302 self_addr_ = IPEndPoint(ip, 8435);
303 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
304 request_.traffic_annotation =
305 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
306 }
307
~QuicHttpStreamTest()308 ~QuicHttpStreamTest() override {
309 session_->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
310 quic::ConnectionCloseBehavior::SILENT_CLOSE);
311 }
312
313 // Adds a packet to the list of expected writes.
AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet)314 void AddWrite(std::unique_ptr<quic::QuicReceivedPacket> packet) {
315 writes_.emplace_back(SYNCHRONOUS, std::move(packet));
316 }
317
AddWrite(IoMode mode,int rv)318 void AddWrite(IoMode mode, int rv) { writes_.emplace_back(mode, rv); }
319
320 // Returns the packet to be written at position |pos|.
GetWrite(size_t pos)321 quic::QuicReceivedPacket* GetWrite(size_t pos) {
322 return writes_[pos].packet.get();
323 }
324
AtEof()325 bool AtEof() {
326 return socket_data_->AllReadDataConsumed() &&
327 socket_data_->AllWriteDataConsumed();
328 }
329
ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet)330 void ProcessPacket(std::unique_ptr<quic::QuicReceivedPacket> packet) {
331 connection_->ProcessUdpPacket(ToQuicSocketAddress(self_addr_),
332 ToQuicSocketAddress(peer_addr_), *packet);
333 }
334
335 // Configures the test fixture to use the list of expected writes.
Initialize()336 void Initialize() {
337 mock_writes_ = std::make_unique<MockWrite[]>(writes_.size());
338 for (size_t i = 0; i < writes_.size(); i++) {
339 if (writes_[i].packet == nullptr) {
340 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
341 } else {
342 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
343 writes_[i].packet->length());
344 }
345 }
346
347 socket_data_ = std::make_unique<StaticSocketDataProvider>(
348 base::span<MockRead>(),
349 base::make_span(mock_writes_.get(), writes_.size()));
350 socket_data_->set_printer(&printer_);
351
352 auto socket = std::make_unique<MockUDPClientSocket>(socket_data_.get(),
353 NetLog::Get());
354 socket->Connect(peer_addr_);
355 runner_ = base::MakeRefCounted<TestTaskRunner>(&clock_);
356 send_algorithm_ = new quic::test::MockSendAlgorithm();
357 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
358 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
359 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
360 .Times(testing::AtLeast(1));
361 EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _, _, _))
362 .Times(AnyNumber());
363 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
364 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
365 EXPECT_CALL(*send_algorithm_, PacingRate(_))
366 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
367 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
368 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
369 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
370 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
371 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
372 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
373 .Times(AnyNumber());
374 helper_ = std::make_unique<QuicChromiumConnectionHelper>(
375 &clock_, &random_generator_);
376 alarm_factory_ =
377 std::make_unique<QuicChromiumAlarmFactory>(runner_.get(), &clock_);
378
379 connection_ = new TestQuicConnection(
380 quic::test::SupportedVersions(version_), connection_id_, peer_addr_,
381 helper_.get(), alarm_factory_.get(),
382 new QuicChromiumPacketWriter(
383 socket.get(),
384 base::SingleThreadTaskRunner::GetCurrentDefault().get()),
385 connection_id_generator_);
386 connection_->set_visitor(&visitor_);
387 connection_->SetSendAlgorithm(send_algorithm_);
388
389 // Load a certificate that is valid for *.example.org
390 scoped_refptr<X509Certificate> test_cert(
391 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
392 EXPECT_TRUE(test_cert.get());
393
394 verify_details_.cert_verify_result.verified_cert = test_cert;
395 verify_details_.cert_verify_result.is_issued_by_known_root = true;
396 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
397
398 base::TimeTicks dns_end = base::TimeTicks::Now();
399 base::TimeTicks dns_start = dns_end - base::Milliseconds(1);
400 session_ = std::make_unique<QuicChromiumClientSession>(
401 connection_, std::move(socket),
402 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
403 &transport_security_state_, &ssl_config_service_,
404 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
405 QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
406 PRIVACY_MODE_DISABLED, SocketTag(),
407 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
408 /*require_dns_https_alpn=*/false),
409 /*require_confirmation=*/false,
410 /*migrate_session_early_v2=*/false,
411 /*migrate_session_on_network_change_v2=*/false,
412 /*default_network=*/handles::kInvalidNetworkHandle,
413 quic::QuicTime::Delta::FromMilliseconds(
414 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
415 /*migrate_idle_session=*/false, /*allow_port_migration=*/false,
416 kDefaultIdleSessionMigrationPeriod, /*multi_port_probing_interval=*/0,
417 kMaxTimeOnNonDefaultNetwork,
418 kMaxMigrationsToNonDefaultNetworkOnWriteError,
419 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
420 kQuicYieldAfterPacketsRead,
421 quic::QuicTime::Delta::FromMilliseconds(
422 kQuicYieldAfterDurationMilliseconds),
423 /*cert_verify_flags=*/0, quic::test::DefaultQuicConfig(),
424 std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
425 dns_start, dns_end, base::DefaultTickClock::GetInstance(),
426 base::SingleThreadTaskRunner::GetCurrentDefault().get(),
427 /*socket_performance_watcher=*/nullptr, HostResolverEndpointResult(),
428 NetLog::Get());
429 session_->Initialize();
430
431 // Blackhole QPACK decoder stream instead of constructing mock writes.
432 session_->qpack_decoder()->set_qpack_stream_sender_delegate(
433 &noop_qpack_stream_sender_delegate_);
434
435 TestCompletionCallback callback;
436 session_->CryptoConnect(callback.callback());
437 stream_ = std::make_unique<QuicHttpStream>(
438 session_->CreateHandle(
439 url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443)),
440 /*dns_aliases=*/std::set<std::string>());
441 }
442
SetRequest(const string & method,const string & path,RequestPriority priority)443 void SetRequest(const string& method,
444 const string& path,
445 RequestPriority priority) {
446 request_headers_ = client_maker_.GetRequestHeaders(method, "https", path);
447 }
448
SetResponse(const string & status,const string & body)449 void SetResponse(const string& status, const string& body) {
450 response_headers_ = server_maker_.GetResponseHeaders(status);
451 response_data_ = body;
452 }
453
ConstructClientDataPacket(uint64_t packet_number,bool fin,std::string_view data)454 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
455 uint64_t packet_number,
456 bool fin,
457 std::string_view data) {
458 return client_maker_.MakeDataPacket(packet_number, stream_id_, fin, data);
459 }
460
ConstructServerDataPacket(uint64_t packet_number,bool fin,std::string_view data)461 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
462 uint64_t packet_number,
463 bool fin,
464 std::string_view data) {
465 return server_maker_.MakeDataPacket(packet_number, stream_id_, fin, data);
466 }
467
InnerConstructRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,RequestPriority request_priority,size_t * spdy_headers_frame_length)468 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
469 uint64_t packet_number,
470 quic::QuicStreamId stream_id,
471 bool fin,
472 RequestPriority request_priority,
473 size_t* spdy_headers_frame_length) {
474 spdy::SpdyPriority priority =
475 ConvertRequestPriorityToQuicPriority(request_priority);
476 return client_maker_.MakeRequestHeadersPacket(
477 packet_number, stream_id, fin, priority, std::move(request_headers_),
478 spdy_headers_frame_length);
479 }
480
481 std::unique_ptr<quic::QuicReceivedPacket>
ConstructRequestHeadersAndDataFramesPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,RequestPriority request_priority,size_t * spdy_headers_frame_length,const std::vector<std::string> & data_writes)482 ConstructRequestHeadersAndDataFramesPacket(
483 uint64_t packet_number,
484 quic::QuicStreamId stream_id,
485 bool fin,
486 RequestPriority request_priority,
487 size_t* spdy_headers_frame_length,
488 const std::vector<std::string>& data_writes) {
489 spdy::SpdyPriority priority =
490 ConvertRequestPriorityToQuicPriority(request_priority);
491 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
492 packet_number, stream_id, fin, priority, std::move(request_headers_),
493 spdy_headers_frame_length, data_writes);
494 }
495
ConstructRequestAndRstPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,RequestPriority request_priority,size_t * spdy_headers_frame_length,quic::QuicRstStreamErrorCode error_code)496 std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
497 uint64_t packet_number,
498 quic::QuicStreamId stream_id,
499 bool fin,
500 RequestPriority request_priority,
501 size_t* spdy_headers_frame_length,
502 quic::QuicRstStreamErrorCode error_code) {
503 spdy::SpdyPriority priority =
504 ConvertRequestPriorityToQuicPriority(request_priority);
505 return client_maker_.MakeRequestHeadersAndRstPacket(
506 packet_number, stream_id, fin, priority, std::move(request_headers_),
507 spdy_headers_frame_length, error_code);
508 }
509
InnerConstructResponseHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,size_t * spdy_headers_frame_length)510 std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
511 uint64_t packet_number,
512 quic::QuicStreamId stream_id,
513 bool fin,
514 size_t* spdy_headers_frame_length) {
515 return server_maker_.MakeResponseHeadersPacket(
516 packet_number, stream_id, fin, std::move(response_headers_),
517 spdy_headers_frame_length);
518 }
519
ConstructResponseHeadersPacket(uint64_t packet_number,bool fin,size_t * spdy_headers_frame_length)520 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
521 uint64_t packet_number,
522 bool fin,
523 size_t* spdy_headers_frame_length) {
524 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
525 spdy_headers_frame_length);
526 }
527
ConstructResponseTrailersPacket(uint64_t packet_number,bool fin,spdy::Http2HeaderBlock trailers,size_t * spdy_headers_frame_length)528 std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
529 uint64_t packet_number,
530 bool fin,
531 spdy::Http2HeaderBlock trailers,
532 size_t* spdy_headers_frame_length) {
533 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id_,
534 fin, std::move(trailers),
535 spdy_headers_frame_length);
536 }
537
ConstructClientRstStreamErrorPacket(uint64_t packet_number)538 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
539 uint64_t packet_number) {
540 return client_maker_.MakeRstPacket(packet_number, stream_id_,
541 quic::QUIC_ERROR_PROCESSING_STREAM);
542 }
543
ConstructAckAndRstStreamPacket(uint64_t packet_number)544 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
545 uint64_t packet_number) {
546 return client_maker_.MakeAckAndRstPacket(packet_number, stream_id_,
547 quic::QUIC_STREAM_CANCELLED, 2, 1);
548 }
549
ConstructClientAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received)550 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
551 uint64_t packet_number,
552 uint64_t largest_received,
553 uint64_t smallest_received) {
554 return client_maker_.MakeAckPacket(packet_number, largest_received,
555 smallest_received);
556 }
557
ConstructServerAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received,uint64_t least_unacked)558 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
559 uint64_t packet_number,
560 uint64_t largest_received,
561 uint64_t smallest_received,
562 uint64_t least_unacked) {
563 return server_maker_.MakeAckPacket(packet_number, largest_received,
564 smallest_received, least_unacked);
565 }
566
ConstructInitialSettingsPacket()567 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
568 return client_maker_.MakeInitialSettingsPacket(1);
569 }
570
ConstructInitialSettingsPacket(int packet_number)571 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
572 int packet_number) {
573 return client_maker_.MakeInitialSettingsPacket(packet_number);
574 }
575
ConstructDataHeader(size_t body_len)576 std::string ConstructDataHeader(size_t body_len) {
577 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
578 body_len, quiche::SimpleBufferAllocator::Get());
579 return std::string(buffer.data(), buffer.size());
580 }
581
ExpectLoadTimingValid(const LoadTimingInfo & load_timing_info,bool session_reused)582 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
583 bool session_reused) {
584 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
585 if (session_reused) {
586 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
587 } else {
588 ExpectConnectTimingHasTimes(
589 load_timing_info.connect_timing,
590 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
591 }
592 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
593 }
594
GetNthClientInitiatedBidirectionalStreamId(int n)595 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
596 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
597 version_.transport_version, n);
598 }
599
GetNthServerInitiatedUnidirectionalStreamId(int n)600 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
601 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
602 version_.transport_version, n);
603 }
604
605 quic::test::QuicFlagSaver saver_;
606
607 const quic::ParsedQuicVersion version_;
608
609 NetLogWithSource net_log_with_source_{
610 NetLogWithSource::Make(NetLog::Get(), NetLogSourceType::NONE)};
611 RecordingNetLogObserver net_log_observer_;
612 scoped_refptr<TestTaskRunner> runner_;
613 std::unique_ptr<MockWrite[]> mock_writes_;
614 quic::MockClock clock_;
615 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
616 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
617 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
618 std::unique_ptr<UploadDataStream> upload_data_stream_;
619 std::unique_ptr<QuicHttpStream> stream_;
620 TransportSecurityState transport_security_state_;
621 SSLConfigServiceDefaults ssl_config_service_;
622
623 // Must outlive `send_algorithm_` and `connection_`.
624 std::unique_ptr<QuicChromiumClientSession> session_;
625 raw_ptr<quic::test::MockSendAlgorithm> send_algorithm_;
626 raw_ptr<TestQuicConnection> connection_;
627
628 quic::QuicCryptoClientConfig crypto_config_;
629 TestCompletionCallback callback_;
630 HttpRequestInfo request_;
631 HttpRequestHeaders headers_;
632 HttpResponseInfo response_;
633 scoped_refptr<IOBufferWithSize> read_buffer_;
634 spdy::Http2HeaderBlock request_headers_;
635 spdy::Http2HeaderBlock response_headers_;
636 string request_data_;
637 string response_data_;
638
639 const quic::QuicStreamId stream_id_;
640
641 const quic::QuicConnectionId connection_id_;
642 QuicTestPacketMaker client_maker_;
643 QuicTestPacketMaker server_maker_;
644 IPEndPoint self_addr_;
645 IPEndPoint peer_addr_;
646 quic::test::MockRandom random_generator_{0};
647 ProofVerifyDetailsChromium verify_details_;
648 MockCryptoClientStreamFactory crypto_client_stream_factory_;
649 std::unique_ptr<StaticSocketDataProvider> socket_data_;
650 QuicPacketPrinter printer_;
651 std::vector<PacketToWrite> writes_;
652 quic::test::MockConnectionIdGenerator connection_id_generator_;
653 quic::test::NoopQpackStreamSenderDelegate noop_qpack_stream_sender_delegate_;
654 base::test::ScopedFeatureList feature_list_;
655 };
656
657 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
658 QuicHttpStreamTest,
659 ::testing::ValuesIn(GetTestParams()),
660 ::testing::PrintToStringParamName());
661
TEST_P(QuicHttpStreamTest,RenewStreamForAuth)662 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
663 Initialize();
664 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
665 }
666
TEST_P(QuicHttpStreamTest,CanReuseConnection)667 TEST_P(QuicHttpStreamTest, CanReuseConnection) {
668 Initialize();
669 EXPECT_FALSE(stream_->CanReuseConnection());
670 }
671
TEST_P(QuicHttpStreamTest,DisableConnectionMigrationForStream)672 TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
673 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
674 Initialize();
675 stream_->RegisterRequest(&request_);
676 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
677 net_log_with_source_,
678 callback_.callback()));
679 QuicChromiumClientStream::Handle* client_stream =
680 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
681 EXPECT_FALSE(client_stream->can_migrate_to_cellular_network());
682 }
683
TEST_P(QuicHttpStreamTest,GetRequest)684 TEST_P(QuicHttpStreamTest, GetRequest) {
685 SetRequest("GET", "/", DEFAULT_PRIORITY);
686 size_t spdy_request_header_frame_length;
687 int packet_number = 1;
688 AddWrite(ConstructInitialSettingsPacket(packet_number++));
689 AddWrite(InnerConstructRequestHeadersPacket(
690 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
691 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
692
693 Initialize();
694
695 request_.method = "GET";
696 request_.url = GURL("https://www.example.org/");
697
698 // Make sure getting load timing from the stream early does not crash.
699 LoadTimingInfo load_timing_info;
700 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
701 stream_->RegisterRequest(&request_);
702 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
703 net_log_with_source_,
704 callback_.callback()));
705 EXPECT_EQ(OK,
706 stream_->SendRequest(headers_, &response_, callback_.callback()));
707
708 // Ack the request.
709 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
710
711 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
712 IsError(ERR_IO_PENDING));
713
714 SetResponse("404", string());
715 size_t spdy_response_header_frame_length;
716 ProcessPacket(ConstructResponseHeadersPacket(
717 2, kFin, &spdy_response_header_frame_length));
718
719 // Now that the headers have been processed, the callback will return.
720 EXPECT_THAT(callback_.WaitForResult(), IsOk());
721 ASSERT_TRUE(response_.headers.get());
722 EXPECT_EQ(404, response_.headers->response_code());
723 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
724 EXPECT_FALSE(response_.response_time.is_null());
725 EXPECT_FALSE(response_.request_time.is_null());
726
727 // There is no body, so this should return immediately.
728 EXPECT_EQ(0,
729 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
730 callback_.callback()));
731 EXPECT_TRUE(stream_->IsResponseBodyComplete());
732 EXPECT_TRUE(AtEof());
733
734 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
735 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
736
737 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
738 // headers and payload.
739 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
740 stream_->GetTotalSentBytes());
741 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
742 stream_->GetTotalReceivedBytes());
743 }
744
TEST_P(QuicHttpStreamTest,LoadTimingTwoRequests)745 TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
746 SetRequest("GET", "/", DEFAULT_PRIORITY);
747 size_t spdy_request_header_frame_length;
748
749 int packet_number = 1;
750 AddWrite(ConstructInitialSettingsPacket(packet_number++));
751 AddWrite(InnerConstructRequestHeadersPacket(
752 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
753 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
754
755 // SetRequest() again for second request as |request_headers_| was moved.
756 SetRequest("GET", "/", DEFAULT_PRIORITY);
757 AddWrite(InnerConstructRequestHeadersPacket(
758 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
759 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
760 AddWrite(
761 ConstructClientAckPacket(packet_number++, 3, 1)); // Ack the responses.
762
763 Initialize();
764
765 request_.method = "GET";
766 request_.url = GURL("https://www.example.org/");
767 // Start first request.
768 stream_->RegisterRequest(&request_);
769 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
770 net_log_with_source_,
771 callback_.callback()));
772 EXPECT_EQ(OK,
773 stream_->SendRequest(headers_, &response_, callback_.callback()));
774
775 // Start a second request.
776 QuicHttpStream stream2(session_->CreateHandle(url::SchemeHostPort(
777 url::kHttpsScheme, "www.example.org", 443)),
778 {} /* dns_aliases */);
779 TestCompletionCallback callback2;
780 stream2.RegisterRequest(&request_);
781 EXPECT_EQ(
782 OK, stream2.InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
783 callback2.callback()));
784 EXPECT_EQ(OK,
785 stream2.SendRequest(headers_, &response_, callback2.callback()));
786
787 // Ack both requests.
788 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
789
790 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
791 IsError(ERR_IO_PENDING));
792 size_t spdy_response_header_frame_length;
793 SetResponse("200", string());
794 ProcessPacket(InnerConstructResponseHeadersPacket(
795 2, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
796 &spdy_response_header_frame_length));
797
798 // Now that the headers have been processed, the callback will return.
799 EXPECT_THAT(callback_.WaitForResult(), IsOk());
800 EXPECT_EQ(200, response_.headers->response_code());
801
802 // There is no body, so this should return immediately.
803 EXPECT_EQ(0,
804 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
805 callback_.callback()));
806 EXPECT_TRUE(stream_->IsResponseBodyComplete());
807
808 LoadTimingInfo load_timing_info;
809 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
810 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
811
812 // SetResponse() again for second request as |response_headers_| was moved.
813 SetResponse("200", string());
814 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
815 IsError(ERR_IO_PENDING));
816
817 ProcessPacket(InnerConstructResponseHeadersPacket(
818 3, GetNthClientInitiatedBidirectionalStreamId(1), kFin,
819 &spdy_response_header_frame_length));
820
821 EXPECT_THAT(callback2.WaitForResult(), IsOk());
822
823 // There is no body, so this should return immediately.
824 EXPECT_EQ(0,
825 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
826 callback2.callback()));
827 EXPECT_TRUE(stream2.IsResponseBodyComplete());
828
829 LoadTimingInfo load_timing_info2;
830 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
831 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
832 }
833
834 // QuicHttpStream does not currently support trailers. It should ignore
835 // trailers upon receiving them.
TEST_P(QuicHttpStreamTest,GetRequestWithTrailers)836 TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
837 SetRequest("GET", "/", DEFAULT_PRIORITY);
838 size_t spdy_request_header_frame_length;
839 int packet_number = 1;
840 AddWrite(ConstructInitialSettingsPacket(packet_number++));
841 AddWrite(InnerConstructRequestHeadersPacket(
842 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
843 DEFAULT_PRIORITY, &spdy_request_header_frame_length));
844 AddWrite(
845 ConstructClientAckPacket(packet_number++, 3, 1)); // Ack the data packet.
846
847 Initialize();
848
849 request_.method = "GET";
850 request_.url = GURL("https://www.example.org/");
851 stream_->RegisterRequest(&request_);
852 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
853 net_log_with_source_,
854 callback_.callback()));
855
856 EXPECT_EQ(OK,
857 stream_->SendRequest(headers_, &response_, callback_.callback()));
858 // Ack the request.
859 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
860
861 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
862 IsError(ERR_IO_PENDING));
863
864 SetResponse("200", string());
865
866 // Send the response headers.
867 size_t spdy_response_header_frame_length;
868 ProcessPacket(ConstructResponseHeadersPacket(
869 2, !kFin, &spdy_response_header_frame_length));
870 // Now that the headers have been processed, the callback will return.
871 EXPECT_THAT(callback_.WaitForResult(), IsOk());
872 ASSERT_TRUE(response_.headers.get());
873 EXPECT_EQ(200, response_.headers->response_code());
874 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
875 EXPECT_FALSE(response_.response_time.is_null());
876 EXPECT_FALSE(response_.request_time.is_null());
877
878 // Send the response body.
879 const char kResponseBody[] = "Hello world!";
880 std::string header = ConstructDataHeader(strlen(kResponseBody));
881 ProcessPacket(ConstructServerDataPacket(3, !kFin, header + kResponseBody));
882 spdy::Http2HeaderBlock trailers;
883 size_t spdy_trailers_frame_length;
884 trailers["foo"] = "bar";
885 ProcessPacket(ConstructResponseTrailersPacket(4, kFin, std::move(trailers),
886 &spdy_trailers_frame_length));
887
888 // Make sure trailers are processed.
889 base::RunLoop().RunUntilIdle();
890
891 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
892 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
893 callback_.callback()));
894 EXPECT_TRUE(stream_->IsResponseBodyComplete());
895
896 EXPECT_EQ(OK,
897 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
898 callback_.callback()));
899
900 EXPECT_TRUE(stream_->IsResponseBodyComplete());
901 EXPECT_TRUE(AtEof());
902
903 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
904 // headers and payload.
905 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
906 stream_->GetTotalSentBytes());
907 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length +
908 strlen(kResponseBody) + header.length() +
909 +spdy_trailers_frame_length),
910 stream_->GetTotalReceivedBytes());
911 // Check that NetLog was filled as expected.
912 auto entries = net_log_observer_.GetEntries();
913 size_t pos = ExpectLogContainsSomewhere(
914 entries, /*min_offset=*/0,
915 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
916 NetLogEventPhase::NONE);
917 pos = ExpectLogContainsSomewhere(
918 entries, /*min_offset=*/pos,
919 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
920 NetLogEventPhase::NONE);
921 ExpectLogContainsSomewhere(
922 entries, /*min_offset=*/pos,
923 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
924 NetLogEventPhase::NONE);
925 }
926
TEST_P(QuicHttpStreamTest,ElideHeadersInNetLog)927 TEST_P(QuicHttpStreamTest, ElideHeadersInNetLog) {
928 Initialize();
929
930 net_log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kDefault);
931
932 // Send first request.
933 SetRequest("GET", "/", DEFAULT_PRIORITY);
934 request_.method = "GET";
935 request_.url = GURL("https://www.example.org/");
936 headers_.SetHeader(HttpRequestHeaders::kCookie, "secret");
937
938 size_t spdy_request_header_frame_length;
939 int outgoing_packet_number = 1;
940 AddWrite(ConstructInitialSettingsPacket(outgoing_packet_number++));
941 AddWrite(InnerConstructRequestHeadersPacket(
942 outgoing_packet_number++, stream_id_, kFin, DEFAULT_PRIORITY,
943 &spdy_request_header_frame_length));
944
945 stream_->RegisterRequest(&request_);
946 EXPECT_THAT(
947 stream_->InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
948 callback_.callback()),
949 IsOk());
950 EXPECT_THAT(stream_->SendRequest(headers_, &response_, callback_.callback()),
951 IsOk());
952 int incoming_packet_number = 1;
953 ProcessPacket(ConstructServerAckPacket(incoming_packet_number++, 1, 1,
954 1)); // Ack the request.
955
956 // Process first response.
957 SetResponse("200", string());
958 response_headers_["set-cookie"] = "secret";
959 size_t spdy_response_header_frame_length;
960 ProcessPacket(ConstructResponseHeadersPacket(
961 incoming_packet_number++, kFin, &spdy_response_header_frame_length));
962 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
963
964 ASSERT_TRUE(response_.headers.get());
965 EXPECT_EQ(200, response_.headers->response_code());
966 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
967 EXPECT_TRUE(response_.headers->HasHeaderValue("set-cookie", "secret"));
968
969 net_log_observer_.SetObserverCaptureMode(
970 NetLogCaptureMode::kIncludeSensitive);
971
972 // Send second request.
973 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(1);
974 request_.url = GURL("https://www.example.org/foo");
975
976 AddWrite(InnerConstructRequestHeadersPacket(
977 outgoing_packet_number++, stream_id, kFin, DEFAULT_PRIORITY,
978 &spdy_request_header_frame_length));
979
980 auto stream = std::make_unique<QuicHttpStream>(
981 session_->CreateHandle(
982 url::SchemeHostPort(url::kHttpsScheme, "www.example.org/foo", 443)),
983 /*dns_aliases=*/std::set<std::string>());
984 stream->RegisterRequest(&request_);
985 EXPECT_THAT(
986 stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_with_source_,
987 callback_.callback()),
988 IsOk());
989 EXPECT_THAT(stream->SendRequest(headers_, &response_, callback_.callback()),
990 IsOk());
991 ProcessPacket(ConstructServerAckPacket(incoming_packet_number++, 1, 1,
992 1)); // Ack the request.
993
994 // Process second response.
995 SetResponse("200", string());
996 response_headers_["set-cookie"] = "secret";
997 ProcessPacket(InnerConstructResponseHeadersPacket(
998 incoming_packet_number++, stream_id, kFin,
999 &spdy_response_header_frame_length));
1000 EXPECT_THAT(stream->ReadResponseHeaders(callback_.callback()), IsOk());
1001
1002 ASSERT_TRUE(response_.headers.get());
1003 EXPECT_EQ(200, response_.headers->response_code());
1004 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1005 EXPECT_TRUE(response_.headers->HasHeaderValue("set-cookie", "secret"));
1006
1007 EXPECT_TRUE(AtEof());
1008
1009 // Check that sensitive header value were stripped
1010 // for the first transaction (logged with NetLogCaptureMode::kDefault)
1011 // but not for the second (logged with NetLogCaptureMode::kIncludeSensitive).
1012 auto entries =
1013 net_log_observer_.GetEntriesWithType(NetLogEventType::HTTP3_HEADERS_SENT);
1014 ASSERT_EQ(2u, entries.size());
1015 EXPECT_TRUE(
1016 CheckHeader(entries[0].params, "cookie", "[6 bytes were stripped]"));
1017 EXPECT_TRUE(CheckHeader(entries[1].params, "cookie", "secret"));
1018
1019 entries = net_log_observer_.GetEntriesWithType(
1020 NetLogEventType::HTTP3_HEADERS_DECODED);
1021 ASSERT_EQ(2u, entries.size());
1022 EXPECT_TRUE(
1023 CheckHeader(entries[0].params, "set-cookie", "[6 bytes were stripped]"));
1024 EXPECT_TRUE(CheckHeader(entries[1].params, "set-cookie", "secret"));
1025 }
1026
1027 // Regression test for http://crbug.com/288128
TEST_P(QuicHttpStreamTest,GetRequestLargeResponse)1028 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
1029 SetRequest("GET", "/", DEFAULT_PRIORITY);
1030 size_t spdy_request_headers_frame_length;
1031 int packet_number = 1;
1032 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1033 AddWrite(InnerConstructRequestHeadersPacket(
1034 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1035 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1036 Initialize();
1037
1038 request_.method = "GET";
1039 request_.url = GURL("https://www.example.org/");
1040
1041 stream_->RegisterRequest(&request_);
1042 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1043 net_log_with_source_,
1044 callback_.callback()));
1045 EXPECT_EQ(OK,
1046 stream_->SendRequest(headers_, &response_, callback_.callback()));
1047
1048 // Ack the request.
1049 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1050
1051 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1052 IsError(ERR_IO_PENDING));
1053
1054 response_headers_[":status"] = "200";
1055 response_headers_[":version"] = "HTTP/1.1";
1056 response_headers_["content-type"] = "text/plain";
1057 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
1058
1059 size_t spdy_response_headers_frame_length;
1060 ProcessPacket(ConstructResponseHeadersPacket(
1061 2, kFin, &spdy_response_headers_frame_length));
1062
1063 // Now that the headers have been processed, the callback will return.
1064 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1065 ASSERT_TRUE(response_.headers.get());
1066 EXPECT_EQ(200, response_.headers->response_code());
1067 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1068
1069 // There is no body, so this should return immediately.
1070 EXPECT_EQ(0,
1071 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1072 callback_.callback()));
1073 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1074 EXPECT_TRUE(AtEof());
1075
1076 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1077 // headers and payload.
1078 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1079 stream_->GetTotalSentBytes());
1080 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
1081 stream_->GetTotalReceivedBytes());
1082 }
1083
1084 // Regression test for http://crbug.com/409101
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendRequest)1085 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
1086 SetRequest("GET", "/", DEFAULT_PRIORITY);
1087 Initialize();
1088
1089 request_.method = "GET";
1090 request_.url = GURL("https://www.example.org/");
1091
1092 stream_->RegisterRequest(&request_);
1093 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1094 net_log_with_source_,
1095 callback_.callback()));
1096
1097 session_->connection()->CloseConnection(
1098 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1099
1100 EXPECT_EQ(ERR_CONNECTION_CLOSED,
1101 stream_->SendRequest(headers_, &response_, callback_.callback()));
1102
1103 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1104 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1105 }
1106
1107 // Regression test for http://crbug.com/584441
TEST_P(QuicHttpStreamTest,GetSSLInfoAfterSessionClosed)1108 TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
1109 SetRequest("GET", "/", DEFAULT_PRIORITY);
1110 Initialize();
1111
1112 request_.method = "GET";
1113 request_.url = GURL("https://www.example.org/");
1114
1115 stream_->RegisterRequest(&request_);
1116 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1117 net_log_with_source_,
1118 callback_.callback()));
1119
1120 SSLInfo ssl_info;
1121 EXPECT_FALSE(ssl_info.is_valid());
1122 stream_->GetSSLInfo(&ssl_info);
1123 EXPECT_TRUE(ssl_info.is_valid());
1124
1125 session_->connection()->CloseConnection(
1126 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1127
1128 SSLInfo ssl_info2;
1129 stream_->GetSSLInfo(&ssl_info2);
1130 EXPECT_TRUE(ssl_info2.is_valid());
1131 }
1132
TEST_P(QuicHttpStreamTest,GetAlternativeService)1133 TEST_P(QuicHttpStreamTest, GetAlternativeService) {
1134 SetRequest("GET", "/", DEFAULT_PRIORITY);
1135 Initialize();
1136
1137 request_.method = "GET";
1138 request_.url = GURL("https://www.example.org/");
1139
1140 stream_->RegisterRequest(&request_);
1141 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1142 net_log_with_source_,
1143 callback_.callback()));
1144
1145 AlternativeService alternative_service;
1146 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service));
1147 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1148 alternative_service);
1149
1150 session_->connection()->CloseConnection(
1151 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1152
1153 AlternativeService alternative_service2;
1154 EXPECT_TRUE(stream_->GetAlternativeService(&alternative_service2));
1155 EXPECT_EQ(AlternativeService(kProtoQUIC, "www.example.org", 443),
1156 alternative_service2);
1157 }
1158
TEST_P(QuicHttpStreamTest,LogGranularQuicConnectionError)1159 TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
1160 SetRequest("GET", "/", DEFAULT_PRIORITY);
1161 size_t spdy_request_headers_frame_length;
1162 int packet_number = 1;
1163 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1164 AddWrite(InnerConstructRequestHeadersPacket(
1165 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1166 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1167 AddWrite(ConstructAckAndRstStreamPacket(3));
1168 Initialize();
1169
1170 request_.method = "GET";
1171 request_.url = GURL("https://www.example.org/");
1172
1173 stream_->RegisterRequest(&request_);
1174 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1175 net_log_with_source_,
1176 callback_.callback()));
1177 EXPECT_EQ(OK,
1178 stream_->SendRequest(headers_, &response_, callback_.callback()));
1179
1180 // Ack the request.
1181 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1182 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1183 IsError(ERR_IO_PENDING));
1184
1185 quic::QuicConnectionCloseFrame frame;
1186 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
1187 session_->connection()->OnConnectionCloseFrame(frame);
1188
1189 NetErrorDetails details;
1190 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
1191 stream_->PopulateNetErrorDetails(&details);
1192 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
1193 }
1194
TEST_P(QuicHttpStreamTest,LogGranularQuicErrorIfHandshakeNotConfirmed)1195 TEST_P(QuicHttpStreamTest, LogGranularQuicErrorIfHandshakeNotConfirmed) {
1196 // By default the test setup defaults handshake to be confirmed. Manually set
1197 // it to be not confirmed.
1198 crypto_client_stream_factory_.set_handshake_mode(
1199 MockCryptoClientStream::ZERO_RTT);
1200
1201 SetRequest("GET", "/", DEFAULT_PRIORITY);
1202 size_t spdy_request_headers_frame_length;
1203 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
1204 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
1205 int packet_number = 1;
1206 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1207 AddWrite(InnerConstructRequestHeadersPacket(
1208 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1209 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1210 Initialize();
1211
1212 request_.method = "GET";
1213 request_.url = GURL("https://www.example.org/");
1214
1215 stream_->RegisterRequest(&request_);
1216 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1217 net_log_with_source_,
1218 callback_.callback()));
1219 EXPECT_EQ(OK,
1220 stream_->SendRequest(headers_, &response_, callback_.callback()));
1221
1222 // Ack the request.
1223 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1224 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1225 IsError(ERR_IO_PENDING));
1226
1227 quic::QuicConnectionCloseFrame frame;
1228 frame.quic_error_code = quic::QUIC_PEER_GOING_AWAY;
1229 session_->connection()->OnConnectionCloseFrame(frame);
1230
1231 NetErrorDetails details;
1232 stream_->PopulateNetErrorDetails(&details);
1233 EXPECT_EQ(quic::QUIC_PEER_GOING_AWAY, details.quic_connection_error);
1234 }
1235
1236 // Regression test for http://crbug.com/409871
TEST_P(QuicHttpStreamTest,SessionClosedBeforeReadResponseHeaders)1237 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1238 SetRequest("GET", "/", DEFAULT_PRIORITY);
1239 size_t spdy_request_headers_frame_length;
1240 int packet_number = 1;
1241 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1242 AddWrite(InnerConstructRequestHeadersPacket(
1243 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1244 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1245 Initialize();
1246
1247 request_.method = "GET";
1248 request_.url = GURL("https://www.example.org/");
1249
1250 stream_->RegisterRequest(&request_);
1251 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1252 net_log_with_source_,
1253 callback_.callback()));
1254
1255 EXPECT_EQ(OK,
1256 stream_->SendRequest(headers_, &response_, callback_.callback()));
1257
1258 session_->connection()->CloseConnection(
1259 quic::QUIC_NO_ERROR, "test", quic::ConnectionCloseBehavior::SILENT_CLOSE);
1260
1261 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
1262
1263 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1264 // headers and payload.
1265 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1266 stream_->GetTotalSentBytes());
1267 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1268 }
1269
TEST_P(QuicHttpStreamTest,SendPostRequest)1270 TEST_P(QuicHttpStreamTest, SendPostRequest) {
1271 SetRequest("POST", "/", DEFAULT_PRIORITY);
1272 size_t spdy_request_headers_frame_length;
1273 int packet_number = 1;
1274 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1275
1276 std::string header = ConstructDataHeader(strlen(kUploadData));
1277 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1278 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1279 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1280 {header, kUploadData}));
1281
1282 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1283
1284 Initialize();
1285
1286 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1287 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
1288 kUploadData, strlen(kUploadData)));
1289 upload_data_stream_ =
1290 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
1291 request_.method = "POST";
1292 request_.url = GURL("https://www.example.org/");
1293 request_.upload_data_stream = upload_data_stream_.get();
1294 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
1295 NetLogWithSource()),
1296 IsOk());
1297
1298 stream_->RegisterRequest(&request_);
1299 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1300 net_log_with_source_,
1301 callback_.callback()));
1302 EXPECT_EQ(OK,
1303 stream_->SendRequest(headers_, &response_, callback_.callback()));
1304
1305 // Ack both packets in the request.
1306 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1307
1308 // Send the response headers (but not the body).
1309 SetResponse("200", string());
1310 size_t spdy_response_headers_frame_length;
1311 ProcessPacket(ConstructResponseHeadersPacket(
1312 2, !kFin, &spdy_response_headers_frame_length));
1313
1314 // The headers have already arrived.
1315 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1316 ASSERT_TRUE(response_.headers.get());
1317 EXPECT_EQ(200, response_.headers->response_code());
1318 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1319
1320 // Send the response body.
1321 const char kResponseBody[] = "Hello world!";
1322 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1323 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1324 // Since the body has already arrived, this should return immediately.
1325 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1326 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1327 callback_.callback()));
1328 EXPECT_EQ(0,
1329 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1330 callback_.callback()));
1331
1332 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1333 EXPECT_TRUE(AtEof());
1334
1335 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1336 // headers and payload.
1337 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1338 strlen(kUploadData) + header.length()),
1339 stream_->GetTotalSentBytes());
1340 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1341 strlen(kResponseBody) + header2.length()),
1342 stream_->GetTotalReceivedBytes());
1343 }
1344
TEST_P(QuicHttpStreamTest,SendPostRequestAndReceiveSoloFin)1345 TEST_P(QuicHttpStreamTest, SendPostRequestAndReceiveSoloFin) {
1346 SetRequest("POST", "/", DEFAULT_PRIORITY);
1347 size_t spdy_request_headers_frame_length;
1348 int packet_number = 1;
1349 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1350 std::string header = ConstructDataHeader(strlen(kUploadData));
1351 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1352 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1353 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1354 {header, kUploadData}));
1355
1356 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1357
1358 Initialize();
1359
1360 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
1361 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
1362 kUploadData, strlen(kUploadData)));
1363 upload_data_stream_ =
1364 std::make_unique<ElementsUploadDataStream>(std::move(element_readers), 0);
1365 request_.method = "POST";
1366 request_.url = GURL("https://www.example.org/");
1367 request_.upload_data_stream = upload_data_stream_.get();
1368 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
1369 NetLogWithSource()),
1370 IsOk());
1371
1372 stream_->RegisterRequest(&request_);
1373 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1374 net_log_with_source_,
1375 callback_.callback()));
1376 EXPECT_EQ(OK,
1377 stream_->SendRequest(headers_, &response_, callback_.callback()));
1378
1379 // Ack both packets in the request.
1380 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1381
1382 // Send the response headers (but not the body).
1383 SetResponse("200", string());
1384 size_t spdy_response_headers_frame_length;
1385 ProcessPacket(ConstructResponseHeadersPacket(
1386 2, !kFin, &spdy_response_headers_frame_length));
1387
1388 // The headers have already arrived.
1389 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1390 ASSERT_TRUE(response_.headers.get());
1391 EXPECT_EQ(200, response_.headers->response_code());
1392 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1393
1394 // Send the response body.
1395 const char kResponseBody[] = "Hello world!";
1396 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1397 ProcessPacket(ConstructServerDataPacket(3, !kFin, header2 + kResponseBody));
1398 // Since the body has already arrived, this should return immediately.
1399 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1400 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1401 callback_.callback()));
1402 ProcessPacket(ConstructServerDataPacket(4, kFin, ""));
1403 EXPECT_EQ(0,
1404 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1405 callback_.callback()));
1406
1407 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1408 EXPECT_TRUE(AtEof());
1409
1410 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1411 // headers and payload.
1412 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1413 strlen(kUploadData) + header.length()),
1414 stream_->GetTotalSentBytes());
1415 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1416 strlen(kResponseBody) + header2.length()),
1417 stream_->GetTotalReceivedBytes());
1418 }
1419
TEST_P(QuicHttpStreamTest,SendChunkedPostRequest)1420 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1421 SetRequest("POST", "/", DEFAULT_PRIORITY);
1422 size_t chunk_size = strlen(kUploadData);
1423 size_t spdy_request_headers_frame_length;
1424 int packet_number = 1;
1425 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1426 std::string header = ConstructDataHeader(chunk_size);
1427 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1428 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1429 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1430 {header, kUploadData}));
1431 AddWrite(
1432 ConstructClientDataPacket(packet_number++, kFin, {header + kUploadData}));
1433
1434 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1435 Initialize();
1436
1437 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1438 auto* chunked_upload_stream =
1439 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1440 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1441
1442 request_.method = "POST";
1443 request_.url = GURL("https://www.example.org/");
1444 request_.upload_data_stream = upload_data_stream_.get();
1445 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1446 TestCompletionCallback().callback(), NetLogWithSource()));
1447
1448 stream_->RegisterRequest(&request_);
1449 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1450 net_log_with_source_,
1451 callback_.callback()));
1452 ASSERT_EQ(ERR_IO_PENDING,
1453 stream_->SendRequest(headers_, &response_, callback_.callback()));
1454
1455 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1456 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1457
1458 // Ack both packets in the request.
1459 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1460
1461 // Send the response headers (but not the body).
1462 SetResponse("200", string());
1463 size_t spdy_response_headers_frame_length;
1464 ProcessPacket(ConstructResponseHeadersPacket(
1465 2, !kFin, &spdy_response_headers_frame_length));
1466
1467 // The headers have already arrived.
1468 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1469 ASSERT_TRUE(response_.headers.get());
1470 EXPECT_EQ(200, response_.headers->response_code());
1471 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1472
1473 // Send the response body.
1474 const char kResponseBody[] = "Hello world!";
1475 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1476 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1477
1478 // Since the body has already arrived, this should return immediately.
1479 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1480 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1481 callback_.callback()));
1482
1483 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1484 EXPECT_TRUE(AtEof());
1485
1486 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1487 // headers and payload.
1488 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1489 strlen(kUploadData) * 2 + header.length() * 2),
1490 stream_->GetTotalSentBytes());
1491 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1492 strlen(kResponseBody) + header2.length()),
1493 stream_->GetTotalReceivedBytes());
1494 }
1495
TEST_P(QuicHttpStreamTest,SendChunkedPostRequestWithFinalEmptyDataPacket)1496 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1497 SetRequest("POST", "/", DEFAULT_PRIORITY);
1498 size_t chunk_size = strlen(kUploadData);
1499 size_t spdy_request_headers_frame_length;
1500 int packet_number = 1;
1501 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1502 std::string header = ConstructDataHeader(chunk_size);
1503
1504 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1505 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1506 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1507 {header, kUploadData}));
1508 AddWrite(ConstructClientDataPacket(packet_number++, kFin, ""));
1509 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1510 Initialize();
1511
1512 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1513 auto* chunked_upload_stream =
1514 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1515 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1516
1517 request_.method = "POST";
1518 request_.url = GURL("https://www.example.org/");
1519 request_.upload_data_stream = upload_data_stream_.get();
1520 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1521 TestCompletionCallback().callback(), NetLogWithSource()));
1522
1523 stream_->RegisterRequest(&request_);
1524 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1525 net_log_with_source_,
1526 callback_.callback()));
1527 ASSERT_EQ(ERR_IO_PENDING,
1528 stream_->SendRequest(headers_, &response_, callback_.callback()));
1529
1530 chunked_upload_stream->AppendData(nullptr, 0, true);
1531 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1532
1533 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1534
1535 // Send the response headers (but not the body).
1536 SetResponse("200", string());
1537 size_t spdy_response_headers_frame_length;
1538 ProcessPacket(ConstructResponseHeadersPacket(
1539 2, !kFin, &spdy_response_headers_frame_length));
1540
1541 // The headers have already arrived.
1542 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1543 ASSERT_TRUE(response_.headers.get());
1544 EXPECT_EQ(200, response_.headers->response_code());
1545 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1546
1547 // Send the response body.
1548 const char kResponseBody[] = "Hello world!";
1549 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1550 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1551
1552 // The body has arrived, but it is delivered asynchronously
1553 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1554 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1555 callback_.callback()));
1556 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1557 EXPECT_TRUE(AtEof());
1558
1559 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1560 // headers and payload.
1561 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1562 strlen(kUploadData) + header.length()),
1563 stream_->GetTotalSentBytes());
1564 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1565 strlen(kResponseBody) + header2.length()),
1566 stream_->GetTotalReceivedBytes());
1567 }
1568
TEST_P(QuicHttpStreamTest,SendChunkedPostRequestWithOneEmptyDataPacket)1569 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1570 SetRequest("POST", "/", DEFAULT_PRIORITY);
1571 size_t spdy_request_headers_frame_length;
1572 int packet_number = 1;
1573 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1574 AddWrite(InnerConstructRequestHeadersPacket(
1575 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1576 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1577 AddWrite(ConstructClientDataPacket(packet_number++, kFin, ""));
1578 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1579 Initialize();
1580
1581 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1582 auto* chunked_upload_stream =
1583 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1584
1585 request_.method = "POST";
1586 request_.url = GURL("https://www.example.org/");
1587 request_.upload_data_stream = upload_data_stream_.get();
1588 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1589 TestCompletionCallback().callback(), NetLogWithSource()));
1590
1591 stream_->RegisterRequest(&request_);
1592 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1593 net_log_with_source_,
1594 callback_.callback()));
1595 ASSERT_EQ(ERR_IO_PENDING,
1596 stream_->SendRequest(headers_, &response_, callback_.callback()));
1597
1598 chunked_upload_stream->AppendData(nullptr, 0, true);
1599 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1600
1601 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1602
1603 // Send the response headers (but not the body).
1604 SetResponse("200", string());
1605 size_t spdy_response_headers_frame_length;
1606 ProcessPacket(ConstructResponseHeadersPacket(
1607 2, !kFin, &spdy_response_headers_frame_length));
1608
1609 // The headers have already arrived.
1610 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1611 ASSERT_TRUE(response_.headers.get());
1612 EXPECT_EQ(200, response_.headers->response_code());
1613 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1614
1615 // Send the response body.
1616 const char kResponseBody[] = "Hello world!";
1617 std::string header = ConstructDataHeader(strlen(kResponseBody));
1618 ProcessPacket(ConstructServerDataPacket(3, kFin, header + kResponseBody));
1619
1620 // The body has arrived, but it is delivered asynchronously
1621 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1622 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1623 callback_.callback()));
1624
1625 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1626 EXPECT_TRUE(AtEof());
1627
1628 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1629 // headers and payload.
1630 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1631 stream_->GetTotalSentBytes());
1632 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1633 strlen(kResponseBody) + header.length()),
1634 stream_->GetTotalReceivedBytes());
1635 }
1636
TEST_P(QuicHttpStreamTest,SendChunkedPostRequestAbortedByResetStream)1637 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestAbortedByResetStream) {
1638 SetRequest("POST", "/", DEFAULT_PRIORITY);
1639 size_t chunk_size = strlen(kUploadData);
1640 size_t spdy_request_headers_frame_length;
1641 int packet_number = 1;
1642
1643 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1644
1645 std::string header = ConstructDataHeader(chunk_size);
1646 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1647 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1648 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1649 {header, kUploadData}));
1650 AddWrite(ConstructClientAckPacket(packet_number++, 3, 1));
1651 AddWrite(client_maker_.MakeAckAndRstPacket(
1652 packet_number++, stream_id_, quic::QUIC_STREAM_NO_ERROR, 4, 1,
1653 /* include_stop_sending_if_v99 = */ false));
1654
1655 Initialize();
1656
1657 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1658 auto* chunked_upload_stream =
1659 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1660 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1661
1662 request_.method = "POST";
1663 request_.url = GURL("https://www.example.org/");
1664 request_.upload_data_stream = upload_data_stream_.get();
1665 ASSERT_THAT(request_.upload_data_stream->Init(
1666 TestCompletionCallback().callback(), NetLogWithSource()),
1667 IsOk());
1668 stream_->RegisterRequest(&request_);
1669 ASSERT_THAT(
1670 stream_->InitializeStream(false, DEFAULT_PRIORITY, net_log_with_source_,
1671 callback_.callback()),
1672 IsOk());
1673 ASSERT_THAT(stream_->SendRequest(headers_, &response_, callback_.callback()),
1674 IsError(ERR_IO_PENDING));
1675
1676 // Ack both packets in the request.
1677 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1678
1679 // Send the response headers (but not the body).
1680 SetResponse("200", string());
1681 size_t spdy_response_headers_frame_length;
1682 ProcessPacket(ConstructResponseHeadersPacket(
1683 2, !kFin, &spdy_response_headers_frame_length));
1684
1685 // Send the response body.
1686 const char kResponseBody[] = "Hello world!";
1687 std::string header2 = ConstructDataHeader(strlen(kResponseBody));
1688 ProcessPacket(ConstructServerDataPacket(3, kFin, header2 + kResponseBody));
1689
1690 // The server uses a STOP_SENDING frame to notify the client that it does not
1691 // need any further data to fully process the request.
1692 ProcessPacket(server_maker_.MakeStopSendingPacket(
1693 4, stream_id_, quic::QUIC_STREAM_NO_ERROR));
1694
1695 // Finish feeding request body to QuicHttpStream. Data will be discarded.
1696 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1697 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1698
1699 // Verify response.
1700 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()), IsOk());
1701 ASSERT_TRUE(response_.headers.get());
1702 EXPECT_EQ(200, response_.headers->response_code());
1703 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1704 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1705 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1706 callback_.callback()));
1707 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1708 EXPECT_TRUE(AtEof());
1709
1710 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1711 // headers and payload.
1712 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1713 strlen(kUploadData) + header.length()),
1714 stream_->GetTotalSentBytes());
1715 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1716 strlen(kResponseBody) + header2.length()),
1717 stream_->GetTotalReceivedBytes());
1718 }
1719
TEST_P(QuicHttpStreamTest,DestroyedEarly)1720 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1721 SetRequest("GET", "/", DEFAULT_PRIORITY);
1722 size_t spdy_request_headers_frame_length;
1723 int packet_number = 1;
1724 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1725 AddWrite(InnerConstructRequestHeadersPacket(
1726 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1727 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1728 AddWrite(ConstructAckAndRstStreamPacket(packet_number++));
1729 Initialize();
1730
1731 request_.method = "GET";
1732 request_.url = GURL("https://www.example.org/");
1733
1734 stream_->RegisterRequest(&request_);
1735 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
1736 net_log_with_source_,
1737 callback_.callback()));
1738 EXPECT_EQ(OK,
1739 stream_->SendRequest(headers_, &response_, callback_.callback()));
1740
1741 // Ack the request.
1742 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1743 EXPECT_THAT(stream_->ReadResponseHeaders(
1744 base::BindOnce(&QuicHttpStreamTest::CloseStream,
1745 base::Unretained(this), stream_.get())),
1746 IsError(ERR_IO_PENDING));
1747
1748 // Send the response with a body.
1749 SetResponse("404", "hello world!");
1750 // In the course of processing this packet, the QuicHttpStream close itself.
1751 size_t response_size = 0;
1752 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin, &response_size));
1753
1754 base::RunLoop().RunUntilIdle();
1755
1756 EXPECT_TRUE(AtEof());
1757
1758 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1759 // headers and payload.
1760 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1761 stream_->GetTotalSentBytes());
1762 // The stream was closed after receiving the headers.
1763 EXPECT_EQ(static_cast<int64_t>(response_size),
1764 stream_->GetTotalReceivedBytes());
1765 }
1766
TEST_P(QuicHttpStreamTest,Priority)1767 TEST_P(QuicHttpStreamTest, Priority) {
1768 SetRequest("GET", "/", MEDIUM);
1769 size_t spdy_request_headers_frame_length;
1770 int packet_number = 1;
1771 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1772 AddWrite(InnerConstructRequestHeadersPacket(
1773 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), kFin,
1774 MEDIUM, &spdy_request_headers_frame_length));
1775 Initialize();
1776
1777 request_.method = "GET";
1778 request_.url = GURL("https://www.example.org/");
1779
1780 stream_->RegisterRequest(&request_);
1781 EXPECT_EQ(OK, stream_->InitializeStream(true, MEDIUM, net_log_with_source_,
1782 callback_.callback()));
1783
1784 EXPECT_EQ(OK,
1785 stream_->SendRequest(headers_, &response_, callback_.callback()));
1786
1787 // Ack the request.
1788 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
1789 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1790 IsError(ERR_IO_PENDING));
1791
1792 // Send the response with a body.
1793 SetResponse("404", "hello world!");
1794 size_t response_size = 0;
1795 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, &response_size));
1796
1797 EXPECT_EQ(OK, callback_.WaitForResult());
1798
1799 EXPECT_TRUE(AtEof());
1800
1801 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1802 // headers and payload.
1803 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1804 stream_->GetTotalSentBytes());
1805 EXPECT_EQ(static_cast<int64_t>(response_size),
1806 stream_->GetTotalReceivedBytes());
1807 }
1808
TEST_P(QuicHttpStreamTest,SessionClosedDuringDoLoop)1809 TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1810 SetRequest("POST", "/", DEFAULT_PRIORITY);
1811 size_t spdy_request_headers_frame_length;
1812 int packet_number = 1;
1813 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1814 std::string header = ConstructDataHeader(strlen(kUploadData));
1815 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1816 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1817 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1818 {header, kUploadData}));
1819
1820 // Second data write will result in a synchronous failure which will close
1821 // the session.
1822 AddWrite(SYNCHRONOUS, ERR_FAILED);
1823 Initialize();
1824
1825 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1826 auto* chunked_upload_stream =
1827 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1828
1829 request_.method = "POST";
1830 request_.url = GURL("https://www.example.org/");
1831 request_.upload_data_stream = upload_data_stream_.get();
1832 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1833 TestCompletionCallback().callback(), NetLogWithSource()));
1834
1835 size_t chunk_size = strlen(kUploadData);
1836 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1837 stream_->RegisterRequest(&request_);
1838 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1839 net_log_with_source_,
1840 callback_.callback()));
1841 QuicHttpStream* stream = stream_.get();
1842 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1843 // SendRequest() completes asynchronously after the final chunk is added.
1844 // Error does not surface yet since packet write is triggered by a packet
1845 // flusher that tries to bundle request body writes.
1846 ASSERT_EQ(ERR_IO_PENDING,
1847 stream->SendRequest(headers_, &response_, callback_.callback()));
1848 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1849 int rv = callback_.WaitForResult();
1850 EXPECT_EQ(OK, rv);
1851 // Error will be surfaced once an attempt to read the response occurs.
1852 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1853 stream->ReadResponseHeaders(callback_.callback()));
1854 }
1855
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendHeadersComplete)1856 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1857 SetRequest("POST", "/", DEFAULT_PRIORITY);
1858 AddWrite(ConstructInitialSettingsPacket());
1859 AddWrite(SYNCHRONOUS, ERR_FAILED);
1860 Initialize();
1861
1862 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1863 auto* chunked_upload_stream =
1864 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1865
1866 request_.method = "POST";
1867 request_.url = GURL("https://www.example.org/");
1868 request_.upload_data_stream = upload_data_stream_.get();
1869 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1870 TestCompletionCallback().callback(), NetLogWithSource()));
1871
1872 stream_->RegisterRequest(&request_);
1873 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1874 net_log_with_source_,
1875 callback_.callback()));
1876 ASSERT_EQ(ERR_IO_PENDING,
1877 stream_->SendRequest(headers_, &response_, callback_.callback()));
1878
1879 // Error will be surfaced once |upload_data_stream| triggers the next write.
1880 size_t chunk_size = strlen(kUploadData);
1881 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1882 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
1883
1884 EXPECT_LE(0, stream_->GetTotalSentBytes());
1885 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1886 }
1887
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendHeadersCompleteReadResponse)1888 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersCompleteReadResponse) {
1889 SetRequest("POST", "/", DEFAULT_PRIORITY);
1890 AddWrite(ConstructInitialSettingsPacket());
1891 AddWrite(SYNCHRONOUS, ERR_FAILED);
1892 Initialize();
1893
1894 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1895 auto* chunked_upload_stream =
1896 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1897
1898 request_.method = "POST";
1899 request_.url = GURL("https://www.example.org/");
1900 request_.upload_data_stream = upload_data_stream_.get();
1901
1902 size_t chunk_size = strlen(kUploadData);
1903 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1904
1905 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1906 TestCompletionCallback().callback(), NetLogWithSource()));
1907
1908 stream_->RegisterRequest(&request_);
1909 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1910 net_log_with_source_,
1911 callback_.callback()));
1912 ASSERT_EQ(OK,
1913 stream_->SendRequest(headers_, &response_, callback_.callback()));
1914
1915 // Error will be surfaced once an attempt to read the response occurs.
1916 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1917 stream_->ReadResponseHeaders(callback_.callback()));
1918
1919 EXPECT_LE(0, stream_->GetTotalSentBytes());
1920 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1921 }
1922
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendBodyComplete)1923 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1924 SetRequest("POST", "/", DEFAULT_PRIORITY);
1925 size_t spdy_request_headers_frame_length;
1926 int packet_number = 1;
1927 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1928 AddWrite(InnerConstructRequestHeadersPacket(
1929 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1930 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
1931 AddWrite(SYNCHRONOUS, ERR_FAILED);
1932 Initialize();
1933
1934 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1935 auto* chunked_upload_stream =
1936 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1937
1938 request_.method = "POST";
1939 request_.url = GURL("https://www.example.org/");
1940 request_.upload_data_stream = upload_data_stream_.get();
1941 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1942 TestCompletionCallback().callback(), NetLogWithSource()));
1943
1944 stream_->RegisterRequest(&request_);
1945 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1946 net_log_with_source_,
1947 callback_.callback()));
1948 ASSERT_EQ(ERR_IO_PENDING,
1949 stream_->SendRequest(headers_, &response_, callback_.callback()));
1950
1951 size_t chunk_size = strlen(kUploadData);
1952 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
1953 // Error does not surface yet since packet write is triggered by a packet
1954 // flusher that tries to bundle request body writes.
1955 ASSERT_EQ(OK, callback_.WaitForResult());
1956 // Error will be surfaced once an attempt to read the response occurs.
1957 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1958 stream_->ReadResponseHeaders(callback_.callback()));
1959
1960 EXPECT_LE(0, stream_->GetTotalSentBytes());
1961 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1962 }
1963
TEST_P(QuicHttpStreamTest,SessionClosedBeforeSendBundledBodyComplete)1964 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBundledBodyComplete) {
1965 SetRequest("POST", "/", DEFAULT_PRIORITY);
1966 size_t spdy_request_headers_frame_length;
1967 int packet_number = 1;
1968 AddWrite(ConstructInitialSettingsPacket(packet_number++));
1969 std::string header = ConstructDataHeader(strlen(kUploadData));
1970 AddWrite(ConstructRequestHeadersAndDataFramesPacket(
1971 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
1972 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
1973 {header, kUploadData}));
1974
1975 AddWrite(SYNCHRONOUS, ERR_FAILED);
1976 Initialize();
1977
1978 upload_data_stream_ = std::make_unique<ChunkedUploadDataStream>(0);
1979 auto* chunked_upload_stream =
1980 static_cast<ChunkedUploadDataStream*>(upload_data_stream_.get());
1981
1982 request_.method = "POST";
1983 request_.url = GURL("https://www.example.org/");
1984 request_.upload_data_stream = upload_data_stream_.get();
1985
1986 size_t chunk_size = strlen(kUploadData);
1987 chunked_upload_stream->AppendData(kUploadData, chunk_size, false);
1988
1989 ASSERT_EQ(OK, request_.upload_data_stream->Init(
1990 TestCompletionCallback().callback(), NetLogWithSource()));
1991
1992 stream_->RegisterRequest(&request_);
1993 ASSERT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
1994 net_log_with_source_,
1995 callback_.callback()));
1996 ASSERT_EQ(ERR_IO_PENDING,
1997 stream_->SendRequest(headers_, &response_, callback_.callback()));
1998
1999 chunked_upload_stream->AppendData(kUploadData, chunk_size, true);
2000
2001 // Error does not surface yet since packet write is triggered by a packet
2002 // flusher that tries to bundle request body writes.
2003 ASSERT_EQ(OK, callback_.WaitForResult());
2004 // Error will be surfaced once an attempt to read the response occurs.
2005 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
2006 stream_->ReadResponseHeaders(callback_.callback()));
2007
2008 EXPECT_LE(0, stream_->GetTotalSentBytes());
2009 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2010 }
2011
TEST_P(QuicHttpStreamTest,DataReadErrorSynchronous)2012 TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2013 SetRequest("POST", "/", DEFAULT_PRIORITY);
2014 size_t spdy_request_headers_frame_length;
2015 int packet_number = 1;
2016 AddWrite(ConstructInitialSettingsPacket(packet_number++));
2017 AddWrite(ConstructRequestAndRstPacket(
2018 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
2019 DEFAULT_PRIORITY, &spdy_request_headers_frame_length,
2020 quic::QUIC_ERROR_PROCESSING_STREAM));
2021
2022 Initialize();
2023
2024 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
2025 ReadErrorUploadDataStream::FailureMode::SYNC);
2026 request_.method = "POST";
2027 request_.url = GURL("https://www.example.org/");
2028 request_.upload_data_stream = upload_data_stream_.get();
2029 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2030 TestCompletionCallback().callback(), NetLogWithSource()));
2031
2032 stream_->RegisterRequest(&request_);
2033 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
2034 net_log_with_source_,
2035 callback_.callback()));
2036
2037 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2038 EXPECT_THAT(result, IsError(ERR_FAILED));
2039
2040 EXPECT_TRUE(AtEof());
2041
2042 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2043 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2044 stream_->GetTotalSentBytes());
2045 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2046 }
2047
TEST_P(QuicHttpStreamTest,DataReadErrorAsynchronous)2048 TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2049 SetRequest("POST", "/", DEFAULT_PRIORITY);
2050 size_t spdy_request_headers_frame_length;
2051 int packet_number = 1;
2052 AddWrite(ConstructInitialSettingsPacket(packet_number++));
2053 AddWrite(InnerConstructRequestHeadersPacket(
2054 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), !kFin,
2055 DEFAULT_PRIORITY, &spdy_request_headers_frame_length));
2056 AddWrite(ConstructClientRstStreamErrorPacket(packet_number++));
2057
2058 Initialize();
2059
2060 upload_data_stream_ = std::make_unique<ReadErrorUploadDataStream>(
2061 ReadErrorUploadDataStream::FailureMode::ASYNC);
2062 request_.method = "POST";
2063 request_.url = GURL("https://www.example.org/");
2064 request_.upload_data_stream = upload_data_stream_.get();
2065 ASSERT_EQ(OK, request_.upload_data_stream->Init(
2066 TestCompletionCallback().callback(), NetLogWithSource()));
2067
2068 stream_->RegisterRequest(&request_);
2069 EXPECT_EQ(OK, stream_->InitializeStream(false, DEFAULT_PRIORITY,
2070 net_log_with_source_,
2071 callback_.callback()));
2072
2073 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2074
2075 ProcessPacket(ConstructServerAckPacket(1, 1, 1, 1));
2076 SetResponse("200", string());
2077
2078 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2079 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
2080
2081 EXPECT_TRUE(AtEof());
2082
2083 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2084 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2085 stream_->GetTotalSentBytes());
2086 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2087 }
2088
TEST_P(QuicHttpStreamTest,GetAcceptChViaAlps)2089 TEST_P(QuicHttpStreamTest, GetAcceptChViaAlps) {
2090 AddWrite(ConstructInitialSettingsPacket());
2091 Initialize();
2092
2093 base::HistogramTester histogram_tester;
2094
2095 session_->OnAcceptChFrameReceivedViaAlps(
2096 {{{"https://www.example.org", "Sec-CH-UA-Platform"}}});
2097
2098 request_.method = "GET";
2099 request_.url = GURL("https://www.example.org/foo");
2100
2101 stream_->RegisterRequest(&request_);
2102 EXPECT_EQ(OK, stream_->InitializeStream(true, DEFAULT_PRIORITY,
2103 net_log_with_source_,
2104 callback_.callback()));
2105 EXPECT_EQ("Sec-CH-UA-Platform", stream_->GetAcceptChViaAlps());
2106 EXPECT_TRUE(AtEof());
2107
2108 histogram_tester.ExpectBucketCount(
2109 "Net.QuicSession.AcceptChFrameReceivedViaAlps", 1, 1);
2110 histogram_tester.ExpectTotalCount(
2111 "Net.QuicSession.AcceptChFrameReceivedViaAlps", 1);
2112 histogram_tester.ExpectBucketCount("Net.QuicSession.AcceptChForOrigin", 1, 1);
2113 histogram_tester.ExpectTotalCount("Net.QuicSession.AcceptChForOrigin", 1);
2114 }
2115
2116 } // namespace net::test
2117