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