• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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_proxy_client_socket_test_base.h"
6 
7 #include "base/memory/ptr_util.h"
8 #include "base/memory/raw_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/strings/strcat.h"
11 #include "base/task/single_thread_task_runner.h"
12 #include "base/time/default_tick_clock.h"
13 #include "net/base/connection_endpoint_metadata.h"
14 #include "net/base/network_anonymization_key.h"
15 #include "net/base/privacy_mode.h"
16 #include "net/base/proxy_chain.h"
17 #include "net/base/proxy_server.h"
18 #include "net/base/proxy_string_util.h"
19 #include "net/base/session_usage.h"
20 #include "net/dns/mock_host_resolver.h"
21 #include "net/dns/public/host_resolver_results.h"
22 #include "net/dns/public/secure_dns_policy.h"
23 #include "net/http/transport_security_state.h"
24 #include "net/log/test_net_log.h"
25 #include "net/log/test_net_log_util.h"
26 #include "net/quic/crypto/proof_verifier_chromium.h"
27 #include "net/quic/mock_crypto_client_stream_factory.h"
28 #include "net/quic/quic_chromium_alarm_factory.h"
29 #include "net/quic/quic_chromium_client_session.h"
30 #include "net/quic/quic_chromium_connection_helper.h"
31 #include "net/quic/quic_chromium_packet_writer.h"
32 #include "net/quic/quic_crypto_client_config_handle.h"
33 #include "net/quic/quic_http_utils.h"
34 #include "net/quic/quic_session_alias_key.h"
35 #include "net/quic/quic_session_key.h"
36 #include "net/quic/test_quic_crypto_client_config_handle.h"
37 #include "net/quic/test_task_runner.h"
38 #include "net/socket/socket_tag.h"
39 #include "net/socket/socket_test_util.h"
40 #include "net/ssl/ssl_config_service_defaults.h"
41 #include "net/test/cert_test_util.h"
42 #include "net/test/gtest_util.h"
43 #include "net/test/test_data_directory.h"
44 #include "net/test/test_with_task_environment.h"
45 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
46 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
47 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
48 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
49 #include "url/scheme_host_port.h"
50 
51 using testing::_;
52 using testing::AnyNumber;
53 using testing::Return;
54 
55 namespace net {
56 
57 QuicProxyClientSocketTestBase::~QuicProxyClientSocketTestBase() = default;
58 
QuicProxyClientSocketTestBase()59 QuicProxyClientSocketTestBase::QuicProxyClientSocketTestBase()
60     : version_(GetParam()),
61       client_data_stream_id1_(quic::QuicUtils::GetFirstBidirectionalStreamId(
62           version_.transport_version,
63           quic::Perspective::IS_CLIENT)),
64       mock_quic_data_(version_),
65       crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting()),
66       connection_id_(quic::test::TestConnectionId(2)),
67       client_maker_(version_,
68                     connection_id_,
69                     &clock_,
70                     kProxyHost,
71                     quic::Perspective::IS_CLIENT),
72       server_maker_(version_,
73                     connection_id_,
74                     &clock_,
75                     kProxyHost,
76                     quic::Perspective::IS_SERVER,
77                     false),
78       user_agent_(kUserAgent),
79       proxy_endpoint_(url::kHttpsScheme, kProxyHost, kProxyPort),
80       destination_endpoint_(url::kHttpsScheme, kOriginHost, kOriginPort),
81       http_auth_cache_(
82           false /* key_server_entries_by_network_anonymization_key */),
83       host_resolver_(std::make_unique<MockCachingHostResolver>()),
84       http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()) {
85   FLAGS_quic_enable_http3_grease_randomness = false;
86   IPAddress ip(192, 0, 2, 33);
87   peer_addr_ = IPEndPoint(ip, 443);
88   clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
89   quic::QuicEnableVersion(version_);
90 }
91 
GetStreamFrameDataLengthFromPacketLength(quic::QuicByteCount packet_length,quic::ParsedQuicVersion version,bool include_version,bool include_diversification_nonce,int connection_id_length,quic::QuicPacketNumberLength packet_number_length,quic::QuicStreamOffset offset)92 size_t QuicProxyClientSocketTestBase::GetStreamFrameDataLengthFromPacketLength(
93     quic::QuicByteCount packet_length,
94     quic::ParsedQuicVersion version,
95     bool include_version,
96     bool include_diversification_nonce,
97     int connection_id_length,
98     quic::QuicPacketNumberLength packet_number_length,
99     quic::QuicStreamOffset offset) {
100   quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
101       quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
102   quiche::QuicheVariableLengthIntegerLength length_length =
103       include_version ? quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2
104                       : quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
105   size_t min_data_length = 1;
106   size_t min_packet_length =
107       quic::test::TaggingEncrypter(quic::ENCRYPTION_FORWARD_SECURE)
108           .GetCiphertextSize(min_data_length) +
109       quic::QuicPacketCreator::StreamFramePacketOverhead(
110           version.transport_version, k8ByteConnectionId, k0ByteConnectionId,
111           include_version, include_diversification_nonce, packet_number_length,
112           retry_token_length_length, length_length, offset);
113 
114   DCHECK(packet_length >= min_packet_length);
115   return min_data_length + packet_length - min_packet_length;
116 }
117 
InitializeSession()118 void QuicProxyClientSocketTestBase::InitializeSession() {
119   auto socket = std::make_unique<MockUDPClientSocket>(
120       mock_quic_data_.InitializeAndGetSequencedSocketData(), NetLog::Get());
121   socket->Connect(peer_addr_);
122   runner_ = base::MakeRefCounted<test::TestTaskRunner>(&clock_);
123   send_algorithm_ = new quic::test::MockSendAlgorithm();
124   EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
125   EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
126   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
127       .Times(testing::AtLeast(1));
128   EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
129       .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
130   EXPECT_CALL(*send_algorithm_, PacingRate(_))
131       .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
132   EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
133   EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
134       .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
135   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
136   EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
137   EXPECT_CALL(*send_algorithm_, GetCongestionControlType()).Times(AnyNumber());
138   EXPECT_CALL(*send_algorithm_, PopulateConnectionStats(_)).Times(AnyNumber());
139   helper_ = std::make_unique<QuicChromiumConnectionHelper>(&clock_,
140                                                            &random_generator_);
141   alarm_factory_ =
142       std::make_unique<QuicChromiumAlarmFactory>(runner_.get(), &clock_);
143 
144   QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
145       socket.get(), base::SingleThreadTaskRunner::GetCurrentDefault().get());
146   quic::QuicConnection* connection = new quic::QuicConnection(
147       connection_id_, quic::QuicSocketAddress(),
148       net::ToQuicSocketAddress(peer_addr_), helper_.get(), alarm_factory_.get(),
149       writer, true /* owns_writer */, quic::Perspective::IS_CLIENT,
150       quic::test::SupportedVersions(version_), connection_id_generator_);
151   connection->set_visitor(&visitor_);
152   connection->SetEncrypter(quic::ENCRYPTION_FORWARD_SECURE,
153                            std::make_unique<quic::test::TaggingEncrypter>(
154                                quic::ENCRYPTION_FORWARD_SECURE));
155   quic::test::QuicConnectionPeer::SetSendAlgorithm(connection, send_algorithm_);
156 
157   // Load a certificate that is valid for *.example.org
158   scoped_refptr<X509Certificate> test_cert(
159       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
160   EXPECT_TRUE(test_cert.get());
161 
162   verify_details_.cert_verify_result.verified_cert = test_cert;
163   verify_details_.cert_verify_result.is_issued_by_known_root = true;
164   crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
165 
166   base::TimeTicks dns_end = base::TimeTicks::Now();
167   base::TimeTicks dns_start = dns_end - base::Milliseconds(1);
168 
169   session_ = std::make_unique<QuicChromiumClientSession>(
170       connection, std::move(socket),
171       /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
172       &transport_security_state_, &ssl_config_service_,
173       base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
174       QuicSessionAliasKey(
175           url::SchemeHostPort(),
176           QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
177                          proxy_chain_, SessionUsage::kDestination, SocketTag(),
178                          NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
179                          /*require_dns_https_alpn=*/false)),
180       /*require_confirmation=*/false,
181       /*migrate_session_early_v2=*/false,
182       /*migrate_session_on_network_change_v2=*/false,
183       /*default_network=*/handles::kInvalidNetworkHandle,
184       quic::QuicTime::Delta::FromMilliseconds(
185           kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
186       /*migrate_idle_session=*/true, /*allow_port_migration=*/false,
187       kDefaultIdleSessionMigrationPeriod, /*multi_port_probing_interval=*/0,
188       kMaxTimeOnNonDefaultNetwork,
189       kMaxMigrationsToNonDefaultNetworkOnWriteError,
190       kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
191       kQuicYieldAfterPacketsRead,
192       quic::QuicTime::Delta::FromMilliseconds(
193           kQuicYieldAfterDurationMilliseconds),
194       /*cert_verify_flags=*/0, quic::test::DefaultQuicConfig(),
195       std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
196       "CONNECTION_UNKNOWN", dns_start, dns_end,
197       base::DefaultTickClock::GetInstance(),
198       base::SingleThreadTaskRunner::GetCurrentDefault().get(),
199       /*socket_performance_watcher=*/nullptr, ConnectionEndpointMetadata(),
200       /*report_ecn=*/true, /*enable_origin_frame=*/true,
201       /*allow_server_preferred_address=*/true,
202       MultiplexedSessionCreationInitiator::kUnknown,
203       NetLogWithSource::Make(NetLogSourceType::NONE));
204 
205   writer->set_delegate(session_.get());
206 
207   session_->Initialize();
208 
209   // Blackhole QPACK decoder stream instead of constructing mock writes.
210   session_->qpack_decoder()->set_qpack_stream_sender_delegate(
211       &noop_qpack_stream_sender_delegate_);
212 
213   TestCompletionCallback callback;
214   EXPECT_THAT(session_->CryptoConnect(callback.callback()), test::IsOk());
215   EXPECT_TRUE(session_->OneRttKeysAvailable());
216 
217   session_handle_ = session_->CreateHandle(
218       url::SchemeHostPort(url::kHttpsScheme, "mail.example.org", 80));
219   EXPECT_THAT(session_handle_->RequestStream(true, callback.callback(),
220                                              TRAFFIC_ANNOTATION_FOR_TESTS),
221               test::IsOk());
222 
223   stream_handle_ = session_handle_->ReleaseStream();
224   EXPECT_TRUE(stream_handle_->IsOpen());
225 }
226 
227 // Helper functions for constructing packets sent by the client
228 
229 std::unique_ptr<quic::QuicReceivedPacket>
ConstructSettingsPacket(uint64_t packet_number)230 QuicProxyClientSocketTestBase::ConstructSettingsPacket(uint64_t packet_number) {
231   return client_maker_.MakeInitialSettingsPacket(packet_number);
232 }
233 
234 std::unique_ptr<quic::QuicReceivedPacket>
ConstructAckAndRstOnlyPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code,uint64_t largest_received,uint64_t smallest_received)235 QuicProxyClientSocketTestBase::ConstructAckAndRstOnlyPacket(
236     uint64_t packet_number,
237     quic::QuicRstStreamErrorCode error_code,
238     uint64_t largest_received,
239     uint64_t smallest_received) {
240   return client_maker_.Packet(packet_number++)
241       .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
242       .AddRstStreamFrame(client_data_stream_id1_, error_code)
243       .Build();
244 }
245 
246 std::unique_ptr<quic::QuicReceivedPacket>
ConstructAckAndRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code,uint64_t largest_received,uint64_t smallest_received)247 QuicProxyClientSocketTestBase::ConstructAckAndRstPacket(
248     uint64_t packet_number,
249     quic::QuicRstStreamErrorCode error_code,
250     uint64_t largest_received,
251     uint64_t smallest_received) {
252   return client_maker_.Packet(packet_number++)
253       .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
254       .AddStopSendingFrame(client_data_stream_id1_, error_code)
255       .AddRstStreamFrame(client_data_stream_id1_, error_code)
256       .Build();
257 }
258 
259 std::unique_ptr<quic::QuicReceivedPacket>
ConstructRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code)260 QuicProxyClientSocketTestBase::ConstructRstPacket(
261     uint64_t packet_number,
262     quic::QuicRstStreamErrorCode error_code) {
263   return client_maker_.Packet(packet_number)
264       .AddStopSendingFrame(client_data_stream_id1_, error_code)
265       .AddRstStreamFrame(client_data_stream_id1_, error_code)
266       .Build();
267 }
268 
269 std::unique_ptr<quic::QuicReceivedPacket>
ConstructConnectRequestPacket(uint64_t packet_number,std::optional<const HttpRequestHeaders> extra_headers,RequestPriority request_priority)270 QuicProxyClientSocketTestBase::ConstructConnectRequestPacket(
271     uint64_t packet_number,
272     std::optional<const HttpRequestHeaders> extra_headers,
273     RequestPriority request_priority) {
274   quiche::HttpHeaderBlock block;
275   PopulateConnectRequestIR(&block, extra_headers);
276   return client_maker_.MakeRequestHeadersPacket(
277       packet_number, client_data_stream_id1_, !kFin,
278       ConvertRequestPriorityToQuicPriority(request_priority), std::move(block),
279       nullptr);
280 }
281 
282 std::unique_ptr<quic::QuicReceivedPacket>
ConstructConnectRequestPacketWithExtraHeaders(uint64_t packet_number,std::vector<std::pair<std::string,std::string>> extra_headers,RequestPriority request_priority)283 QuicProxyClientSocketTestBase::ConstructConnectRequestPacketWithExtraHeaders(
284     uint64_t packet_number,
285     std::vector<std::pair<std::string, std::string>> extra_headers,
286     RequestPriority request_priority) {
287   quiche::HttpHeaderBlock block;
288   block[":method"] = "CONNECT";
289   block[":authority"] =
290       HostPortPair::FromSchemeHostPort(destination_endpoint_).ToString();
291   for (const auto& header : extra_headers) {
292     block[header.first] = header.second;
293   }
294   return client_maker_.MakeRequestHeadersPacket(
295       packet_number, client_data_stream_id1_, !kFin,
296       ConvertRequestPriorityToQuicPriority(request_priority), std::move(block),
297       nullptr);
298 }
299 
300 std::unique_ptr<quic::QuicReceivedPacket>
ConstructConnectAuthRequestPacket(uint64_t packet_number)301 QuicProxyClientSocketTestBase::ConstructConnectAuthRequestPacket(
302     uint64_t packet_number) {
303   RequestPriority request_priority = LOWEST;
304   quiche::HttpHeaderBlock block;
305   PopulateConnectRequestIR(&block, /*extra_headers=*/std::nullopt);
306   block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
307   return client_maker_.MakeRequestHeadersPacket(
308       packet_number, client_data_stream_id1_, !kFin,
309       ConvertRequestPriorityToQuicPriority(request_priority), std::move(block),
310       nullptr);
311 }
312 
313 std::unique_ptr<quic::QuicReceivedPacket>
ConstructDataPacket(uint64_t packet_number,std::string_view data)314 QuicProxyClientSocketTestBase::ConstructDataPacket(uint64_t packet_number,
315                                                    std::string_view data) {
316   return client_maker_.Packet(packet_number)
317       .AddStreamFrame(client_data_stream_id1_, !kFin, data)
318       .Build();
319 }
320 
321 std::unique_ptr<quic::QuicReceivedPacket>
ConstructDatagramPacket(uint64_t packet_number,std::string_view data)322 QuicProxyClientSocketTestBase::ConstructDatagramPacket(uint64_t packet_number,
323                                                        std::string_view data) {
324   return client_maker_.Packet(packet_number).AddMessageFrame(data).Build();
325 }
326 
327 std::unique_ptr<quic::QuicReceivedPacket>
ConstructAckAndDataPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received,std::string_view data)328 QuicProxyClientSocketTestBase::ConstructAckAndDataPacket(
329     uint64_t packet_number,
330     uint64_t largest_received,
331     uint64_t smallest_received,
332     std::string_view data) {
333   return client_maker_.Packet(packet_number)
334       .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
335       .AddStreamFrame(client_data_stream_id1_, !kFin, data)
336       .Build();
337 }
338 
339 std::unique_ptr<quic::QuicReceivedPacket>
ConstructAckAndDatagramPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received,std::string_view data)340 QuicProxyClientSocketTestBase::ConstructAckAndDatagramPacket(
341     uint64_t packet_number,
342     uint64_t largest_received,
343     uint64_t smallest_received,
344     std::string_view data) {
345   return client_maker_.MakeAckAndDatagramPacket(packet_number, largest_received,
346                                                 smallest_received, data);
347 }
348 
349 std::unique_ptr<quic::QuicReceivedPacket>
ConstructAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received)350 QuicProxyClientSocketTestBase::ConstructAckPacket(uint64_t packet_number,
351                                                   uint64_t largest_received,
352                                                   uint64_t smallest_received) {
353   return client_maker_.Packet(packet_number)
354       .AddAckFrame(1, largest_received, smallest_received)
355       .Build();
356 }
357 
358 // Helper functions for constructing packets sent by the server
359 
360 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code)361 QuicProxyClientSocketTestBase::ConstructServerRstPacket(
362     uint64_t packet_number,
363     quic::QuicRstStreamErrorCode error_code) {
364   return server_maker_.Packet(packet_number)
365       .AddStopSendingFrame(client_data_stream_id1_, error_code)
366       .AddRstStreamFrame(client_data_stream_id1_, error_code)
367       .Build();
368 }
369 
370 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerDataPacket(uint64_t packet_number,std::string_view data)371 QuicProxyClientSocketTestBase::ConstructServerDataPacket(
372     uint64_t packet_number,
373     std::string_view data) {
374   return server_maker_.Packet(packet_number)
375       .AddStreamFrame(client_data_stream_id1_, !kFin, data)
376       .Build();
377 }
378 
379 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerDatagramPacket(uint64_t packet_number,std::string_view data)380 QuicProxyClientSocketTestBase::ConstructServerDatagramPacket(
381     uint64_t packet_number,
382     std::string_view data) {
383   return server_maker_.Packet(packet_number).AddMessageFrame(data).Build();
384 }
385 
386 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerDataFinPacket(uint64_t packet_number,std::string_view data)387 QuicProxyClientSocketTestBase::ConstructServerDataFinPacket(
388     uint64_t packet_number,
389     std::string_view data) {
390   return server_maker_.Packet(packet_number)
391       .AddStreamFrame(client_data_stream_id1_, kFin, data)
392       .Build();
393 }
394 
395 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerConnectReplyPacket(uint64_t packet_number,bool fin,size_t * header_length,std::optional<const HttpRequestHeaders> extra_headers)396 QuicProxyClientSocketTestBase::ConstructServerConnectReplyPacket(
397     uint64_t packet_number,
398     bool fin,
399     size_t* header_length,
400     std::optional<const HttpRequestHeaders> extra_headers) {
401   quiche::HttpHeaderBlock block;
402   block[":status"] = "200";
403 
404   if (extra_headers) {
405     HttpRequestHeaders::Iterator it(*extra_headers);
406     while (it.GetNext()) {
407       std::string name = base::ToLowerASCII(it.name());
408       block[name] = it.value();
409     }
410   }
411 
412   return server_maker_.MakeResponseHeadersPacket(
413       packet_number, client_data_stream_id1_, fin, std::move(block),
414       header_length);
415 }
416 
417 std::unique_ptr<quic::QuicReceivedPacket> QuicProxyClientSocketTestBase::
ConstructServerConnectReplyPacketWithExtraHeaders(uint64_t packet_number,bool fin,std::vector<std::pair<std::string,std::string>> extra_headers)418     ConstructServerConnectReplyPacketWithExtraHeaders(
419         uint64_t packet_number,
420         bool fin,
421         std::vector<std::pair<std::string, std::string>> extra_headers) {
422   quiche::HttpHeaderBlock block;
423   block[":status"] = "200";
424   for (const auto& header : extra_headers) {
425     block[header.first] = header.second;
426   }
427 
428   return server_maker_.MakeResponseHeadersPacket(
429       packet_number, client_data_stream_id1_, fin, std::move(block), nullptr);
430 }
431 
432 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerConnectAuthReplyPacket(uint64_t packet_number,bool fin)433 QuicProxyClientSocketTestBase::ConstructServerConnectAuthReplyPacket(
434     uint64_t packet_number,
435     bool fin) {
436   quiche::HttpHeaderBlock block;
437   block[":status"] = "407";
438   block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
439   return server_maker_.MakeResponseHeadersPacket(
440       packet_number, client_data_stream_id1_, fin, std::move(block), nullptr);
441 }
442 
443 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerConnectRedirectReplyPacket(uint64_t packet_number,bool fin)444 QuicProxyClientSocketTestBase::ConstructServerConnectRedirectReplyPacket(
445     uint64_t packet_number,
446     bool fin) {
447   quiche::HttpHeaderBlock block;
448   block[":status"] = "302";
449   block["location"] = kRedirectUrl;
450   block["set-cookie"] = "foo=bar";
451   return server_maker_.MakeResponseHeadersPacket(
452       packet_number, client_data_stream_id1_, fin, std::move(block), nullptr);
453 }
454 
455 std::unique_ptr<quic::QuicReceivedPacket>
ConstructServerConnectErrorReplyPacket(uint64_t packet_number,bool fin)456 QuicProxyClientSocketTestBase::ConstructServerConnectErrorReplyPacket(
457     uint64_t packet_number,
458     bool fin) {
459   quiche::HttpHeaderBlock block;
460   block[":status"] = "500";
461 
462   return server_maker_.MakeResponseHeadersPacket(
463       packet_number, client_data_stream_id1_, fin, std::move(block), nullptr);
464 }
465 
ResumeAndRun()466 void QuicProxyClientSocketTestBase::ResumeAndRun() {
467   // Run until the pause, if the provider isn't paused yet.
468   SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
469   data->RunUntilPaused();
470   data->Resume();
471   base::RunLoop().RunUntilIdle();
472 }
473 
ConstructDataHeader(size_t body_len)474 std::string QuicProxyClientSocketTestBase::ConstructDataHeader(
475     size_t body_len) {
476   quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
477       body_len, quiche::SimpleBufferAllocator::Get());
478   return std::string(buffer.data(), buffer.size());
479 }
480 }  // namespace net
481