[IP Protection] Tunnel HTTP requests over QUIC proxies
This CL makes proxied HTTP requests over QUIC proxies use CONNECT
tunnels instead of sending requests with the full URL to the proxy
directly. Support for configuring QUIC proxies other than for IP
Protection is being removed for now, and usage was already very low,
so this change is not expected to cause additional breakage.
This change obviates the need to fix a potential issue
identified in
https://chromium-review.googlesource.com/c/chromium/src/+/5205530/comment/678af427_eedba0ef/
where for the proxied GET requests sent to the proxy server,
HttpStreamFactory::Job::DoInitConnectionImplQuic uses
QuicSessionRequests with the destination corresponding to the
proxy server but HttpStreamFactory::Job::HasAvailableQuicSession
looks for existing QuicSessions where the destination
corresponds to the request URL.
This aligns the QUIC HTTP proxying behavior with what's
implemented for HTTP/SPDY proxying when multi-proxy chains are
in use (see:
https://chromium-review.googlesource.com/c/chromium/src/+/5085087)
Bug: 1520929
Change-Id: I1cebb46b36cecb1ef940e498563a3b052ff71b41
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5241818
Commit-Queue: Andrew Williams <[email protected]>
Reviewed-by: Kenichi Ishibashi <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1255385}
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index df237d9..d1cca834 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -719,14 +719,6 @@
expected, 443, kQuic200RespStatusLine, version_, std::nullopt);
}
- void SendRequestAndExpectQuicResponseFromProxyOnPort(
- std::string_view expected,
- uint16_t port,
- const ProxyChain& proxy_chain) {
- SendRequestAndExpectQuicResponseMaybeFromProxy(
- expected, port, kQuic200RespStatusLine, version_, proxy_chain);
- }
-
void AddQuicAlternateProtocolMapping(
MockCryptoClientStream::HandshakeMode handshake_mode,
const NetworkAnonymizationKey& network_anonymization_key =
@@ -1501,11 +1493,12 @@
}
TEST_P(QuicNetworkTransactionTest, QuicProxy) {
+ DisablePriorityHeader();
session_params_.enable_quic = true;
const auto kQuicProxyChain =
ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
- ProxyServer::SCHEME_QUIC, "mail.example.org", 70)});
+ ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
proxy_resolution_service_ =
ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
{kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
@@ -1516,21 +1509,58 @@
ConstructInitialSettingsPacket(packet_num++));
mock_quic_data.AddWrite(
SYNCHRONOUS,
+ ConstructClientPriorityPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
+ DEFAULT_PRIORITY));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
ConstructClientRequestHeadersPacket(
- packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
- GetRequestHeaders("GET", "http", "/")));
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:80"),
+ false));
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
1, GetNthClientInitiatedBidirectionalStreamId(0), false,
GetResponseHeaders("200")));
+
+ const char kGetRequest[] =
+ "GET / HTTP/1.1\r\n"
+ "Host: mail.example.org\r\n"
+ "Connection: keep-alive\r\n\r\n";
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndDataPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
+ false, ConstructDataFrame(kGetRequest)));
+
+ const char kGetResponse[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 11\r\n\r\n";
+ ASSERT_EQ(strlen(kHttpRespData), 11u);
+
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
- 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
- ConstructDataFrame(kQuicRespData)));
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ ConstructDataFrame(kGetResponse)));
+
+ mock_quic_data.AddRead(
+ ASYNC, ConstructServerDataPacket(
+ 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ ConstructDataFrame(kHttpRespData)));
mock_quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckPacket(packet_num++, 2, 1));
- mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
+ ConstructClientAckPacket(packet_num++, 3, 2));
+ mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
+
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
+ StreamCancellationQpackDecoderInstruction(0)));
+
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRstPacket(packet_num++,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED));
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
@@ -1541,11 +1571,20 @@
request_.url = GURL("http://mail.example.org/");
CreateSession();
-
- SendRequestAndExpectQuicResponseFromProxyOnPort(
- kQuicRespData,
+ AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
+ SendRequestAndExpectHttpResponseFromProxy(
+ kHttpRespData,
kQuicProxyChain.GetProxyServer(/*chain_index=*/0).GetPort(),
kQuicProxyChain);
+
+ // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
+ // proxy socket to disconnect.
+ NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
+ EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
+
EXPECT_TRUE(
test_socket_performance_watcher_factory_.rtt_notification_received());
}
@@ -1554,6 +1593,7 @@
// connection through a QUIC proxy, the certificate exhibited by the proxy is
// checked against the proxy hostname, not the origin hostname.
TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
+ DisablePriorityHeader();
const std::string kOriginHost = "mail.example.com";
const std::string kProxyHost = "proxy.example.org";
@@ -1573,21 +1613,59 @@
ConstructInitialSettingsPacket(packet_num++));
mock_quic_data.AddWrite(
SYNCHRONOUS,
+ ConstructClientPriorityPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
+ DEFAULT_PRIORITY));
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
ConstructClientRequestHeadersPacket(
- packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
- GetRequestHeaders("GET", "http", "/")));
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.com:80"),
+ false));
mock_quic_data.AddRead(
ASYNC, ConstructServerResponseHeadersPacket(
1, GetNthClientInitiatedBidirectionalStreamId(0), false,
GetResponseHeaders("200")));
+
+ const char kGetRequest[] =
+ "GET / HTTP/1.1\r\n"
+ "Host: mail.example.com\r\n"
+ "Connection: keep-alive\r\n\r\n";
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientAckAndDataPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
+ false, ConstructDataFrame(kGetRequest)));
+
+ const char kGetResponse[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 11\r\n\r\n";
+ ASSERT_EQ(strlen(kHttpRespData), 11u);
+
mock_quic_data.AddRead(
ASYNC, ConstructServerDataPacket(
- 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
- ConstructDataFrame(kQuicRespData)));
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ ConstructDataFrame(kGetResponse)));
+
+ mock_quic_data.AddRead(
+ ASYNC, ConstructServerDataPacket(
+ 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ ConstructDataFrame(kHttpRespData)));
mock_quic_data.AddWrite(SYNCHRONOUS,
- ConstructClientAckPacket(packet_num++, 2, 1));
- mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
- mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
+ ConstructClientAckPacket(packet_num++, 3, 2));
+ mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
+
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
+ StreamCancellationQpackDecoderInstruction(0)));
+
+ mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ ConstructClientRstPacket(packet_num++,
+ GetNthClientInitiatedBidirectionalStreamId(0),
+ quic::QUIC_STREAM_CANCELLED));
+
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
scoped_refptr<X509Certificate> cert(
@@ -1607,8 +1685,8 @@
AddHangingNonAlternateProtocolSocketData();
CreateSession();
AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
- SendRequestAndExpectQuicResponseFromProxyOnPort(
- kQuicRespData,
+ SendRequestAndExpectHttpResponseFromProxy(
+ kHttpRespData,
kQuicProxyChain.GetProxyServer(/*chain_index=*/0).GetPort(),
kQuicProxyChain);
}
@@ -7484,296 +7562,256 @@
context_.params()->origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));
- // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
- // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
- // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
- // the same way as the HTTP over H2 proxy case.
- for (bool use_proxy : {false, true}) {
- SCOPED_TRACE(use_proxy);
+ GURL url1 = GURL("https://mail.example.org/1");
+ GURL url2 = GURL("https://mail.example.org/2");
+ GURL url3 = GURL("https://mail.example.org/3");
- if (use_proxy) {
- proxy_resolution_service_ =
- ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
- {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
- ProxyServer::SCHEME_QUIC, "mail.example.org", 443)})},
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ for (bool partition_connections : {false, true}) {
+ SCOPED_TRACE(partition_connections);
+
+ base::test::ScopedFeatureList feature_list;
+ if (partition_connections) {
+ feature_list.InitAndEnableFeature(
+ features::kPartitionConnectionsByNetworkIsolationKey);
} else {
- proxy_resolution_service_ =
- ConfiguredProxyResolutionService::CreateDirect();
+ feature_list.InitAndDisableFeature(
+ features::kPartitionConnectionsByNetworkIsolationKey);
}
- GURL url1;
- GURL url2;
- GURL url3;
- if (use_proxy) {
- url1 = GURL("http://mail.example.org/1");
- url2 = GURL("http://mail.example.org/2");
- url3 = GURL("http://mail.example.org/3");
+ // Reads and writes for the unpartitioned case, where only one socket is
+ // used.
+
+ context_.params()->origins_to_force_quic_on.insert(
+ HostPortPair::FromString("mail.example.org:443"));
+
+ MockQuicData unpartitioned_mock_quic_data(version_);
+ QuicTestPacketMaker client_maker1(
+ version_,
+ quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
+ context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
+ /*client_priority_uses_incremental=*/true,
+ /*use_priority_header=*/true);
+ QuicTestPacketMaker server_maker1(
+ version_,
+ quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
+ context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
+ /*client_priority_uses_incremental=*/false,
+ /*use_priority_header=*/false);
+
+ int packet_num = 1;
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
+
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ client_maker1.MakeRequestHeadersPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+ GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
+ unpartitioned_mock_quic_data.AddRead(
+ ASYNC, server_maker1.MakeResponseHeadersPacket(
+ 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ GetResponseHeaders("200"), nullptr));
+ const char kRespData1[] = "1";
+ unpartitioned_mock_quic_data.AddRead(
+ ASYNC, server_maker1.MakeDataPacket(
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
+ ConstructDataFrame(kRespData1)));
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
+
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ client_maker1.MakeRequestHeadersPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+ GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
+ unpartitioned_mock_quic_data.AddRead(
+ ASYNC, server_maker1.MakeResponseHeadersPacket(
+ 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
+ GetResponseHeaders("200"), nullptr));
+ const char kRespData2[] = "2";
+ unpartitioned_mock_quic_data.AddRead(
+ ASYNC, server_maker1.MakeDataPacket(
+ 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
+ ConstructDataFrame(kRespData2)));
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
+
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS,
+ client_maker1.MakeRequestHeadersPacket(
+ packet_num++, GetNthClientInitiatedBidirectionalStreamId(2), true,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+ GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
+ unpartitioned_mock_quic_data.AddRead(
+ ASYNC, server_maker1.MakeResponseHeadersPacket(
+ 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
+ GetResponseHeaders("200"), nullptr));
+ const char kRespData3[] = "3";
+ unpartitioned_mock_quic_data.AddRead(
+ ASYNC, server_maker1.MakeDataPacket(
+ 6, GetNthClientInitiatedBidirectionalStreamId(2), true,
+ ConstructDataFrame(kRespData3)));
+ unpartitioned_mock_quic_data.AddWrite(
+ SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
+
+ unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+
+ // Reads and writes for the partitioned case, where two sockets are used.
+
+ MockQuicData partitioned_mock_quic_data1(version_);
+ QuicTestPacketMaker client_maker2(
+ version_,
+ quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
+ context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
+ /*client_priority_uses_incremental=*/true,
+ /*use_priority_header=*/true);
+ QuicTestPacketMaker server_maker2(
+ version_,
+ quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
+ context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
+ /*client_priority_uses_incremental=*/false,
+ /*use_priority_header=*/false);
+
+ int packet_num2 = 1;
+ partitioned_mock_quic_data1.AddWrite(
+ SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(packet_num2++));
+
+ partitioned_mock_quic_data1.AddWrite(
+ SYNCHRONOUS,
+ client_maker2.MakeRequestHeadersPacket(
+ packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+ GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
+ partitioned_mock_quic_data1.AddRead(
+ ASYNC, server_maker2.MakeResponseHeadersPacket(
+ 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ GetResponseHeaders("200"), nullptr));
+ partitioned_mock_quic_data1.AddRead(
+ ASYNC, server_maker2.MakeDataPacket(
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
+ ConstructDataFrame(kRespData1)));
+ partitioned_mock_quic_data1.AddWrite(
+ SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
+
+ partitioned_mock_quic_data1.AddWrite(
+ SYNCHRONOUS,
+ client_maker2.MakeRequestHeadersPacket(
+ packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1), true,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+ GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
+ partitioned_mock_quic_data1.AddRead(
+ ASYNC, server_maker2.MakeResponseHeadersPacket(
+ 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
+ GetResponseHeaders("200"), nullptr));
+ partitioned_mock_quic_data1.AddRead(
+ ASYNC, server_maker2.MakeDataPacket(
+ 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
+ ConstructDataFrame(kRespData3)));
+ partitioned_mock_quic_data1.AddWrite(
+ SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
+
+ partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+
+ MockQuicData partitioned_mock_quic_data2(version_);
+ QuicTestPacketMaker client_maker3(
+ version_,
+ quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
+ context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
+ /*client_priority_uses_incremental=*/true,
+ /*use_priority_header=*/true);
+ QuicTestPacketMaker server_maker3(
+ version_,
+ quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
+ context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
+ /*client_priority_uses_incremental=*/false,
+ /*use_priority_header=*/false);
+
+ int packet_num3 = 1;
+ partitioned_mock_quic_data2.AddWrite(
+ SYNCHRONOUS, client_maker3.MakeInitialSettingsPacket(packet_num3++));
+
+ partitioned_mock_quic_data2.AddWrite(
+ SYNCHRONOUS,
+ client_maker3.MakeRequestHeadersPacket(
+ packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0), true,
+ ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
+ GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
+ partitioned_mock_quic_data2.AddRead(
+ ASYNC, server_maker3.MakeResponseHeadersPacket(
+ 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
+ GetResponseHeaders("200"), nullptr));
+ partitioned_mock_quic_data2.AddRead(
+ ASYNC, server_maker3.MakeDataPacket(
+ 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
+ ConstructDataFrame(kRespData2)));
+ partitioned_mock_quic_data2.AddWrite(
+ SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
+
+ partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+
+ if (partition_connections) {
+ partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
+ partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
} else {
- url1 = GURL("https://mail.example.org/1");
- url2 = GURL("https://mail.example.org/2");
- url3 = GURL("https://mail.example.org/3");
+ unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
}
- for (bool partition_connections : {false, true}) {
- SCOPED_TRACE(partition_connections);
+ CreateSession();
- base::test::ScopedFeatureList feature_list;
- if (partition_connections) {
- feature_list.InitAndEnableFeature(
- features::kPartitionConnectionsByNetworkIsolationKey);
- } else {
- feature_list.InitAndDisableFeature(
- features::kPartitionConnectionsByNetworkIsolationKey);
- }
+ TestCompletionCallback callback;
+ HttpRequestInfo request1;
+ request1.method = "GET";
+ request1.url = GURL(url1);
+ request1.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+ request1.network_isolation_key = network_isolation_key1;
+ request1.network_anonymization_key = network_anonymization_key1;
+ HttpNetworkTransaction trans1(LOWEST, session_.get());
+ int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ std::string response_data1;
+ EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
+ EXPECT_EQ(kRespData1, response_data1);
- // Reads and writes for the unpartitioned case, where only one socket is
- // used.
+ HttpRequestInfo request2;
+ request2.method = "GET";
+ request2.url = GURL(url2);
+ request2.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+ request2.network_isolation_key = network_isolation_key2;
+ request2.network_anonymization_key = network_anonymization_key2;
+ HttpNetworkTransaction trans2(LOWEST, session_.get());
+ rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ std::string response_data2;
+ EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
+ EXPECT_EQ(kRespData2, response_data2);
- context_.params()->origins_to_force_quic_on.insert(
- HostPortPair::FromString("mail.example.org:443"));
+ HttpRequestInfo request3;
+ request3.method = "GET";
+ request3.url = GURL(url3);
+ request3.traffic_annotation =
+ net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
+ request3.network_isolation_key = network_isolation_key1;
+ request3.network_anonymization_key = network_anonymization_key1;
- MockQuicData unpartitioned_mock_quic_data(version_);
- QuicTestPacketMaker client_maker1(
- version_,
- quic::QuicUtils::CreateRandomConnectionId(
- context_.random_generator()),
- context_.clock(), kDefaultServerHostName,
- quic::Perspective::IS_CLIENT,
- /*client_priority_uses_incremental=*/true,
- /*use_priority_header=*/true);
- QuicTestPacketMaker server_maker1(
- version_,
- quic::QuicUtils::CreateRandomConnectionId(
- context_.random_generator()),
- context_.clock(), kDefaultServerHostName,
- quic::Perspective::IS_SERVER,
- /*client_priority_uses_incremental=*/false,
- /*use_priority_header=*/false);
+ HttpNetworkTransaction trans3(LOWEST, session_.get());
+ rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
+ EXPECT_THAT(callback.GetResult(rv), IsOk());
+ std::string response_data3;
+ EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
+ EXPECT_EQ(kRespData3, response_data3);
- int packet_num = 1;
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
-
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS,
- client_maker1.MakeRequestHeadersPacket(
- packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
- ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
- unpartitioned_mock_quic_data.AddRead(
- ASYNC, server_maker1.MakeResponseHeadersPacket(
- 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
- GetResponseHeaders("200"), nullptr));
- const char kRespData1[] = "1";
- unpartitioned_mock_quic_data.AddRead(
- ASYNC, server_maker1.MakeDataPacket(
- 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
- ConstructDataFrame(kRespData1)));
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
-
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS,
- client_maker1.MakeRequestHeadersPacket(
- packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
- ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
- unpartitioned_mock_quic_data.AddRead(
- ASYNC, server_maker1.MakeResponseHeadersPacket(
- 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
- GetResponseHeaders("200"), nullptr));
- const char kRespData2[] = "2";
- unpartitioned_mock_quic_data.AddRead(
- ASYNC, server_maker1.MakeDataPacket(
- 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
- ConstructDataFrame(kRespData2)));
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
-
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS,
- client_maker1.MakeRequestHeadersPacket(
- packet_num++, GetNthClientInitiatedBidirectionalStreamId(2), true,
- ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
- unpartitioned_mock_quic_data.AddRead(
- ASYNC, server_maker1.MakeResponseHeadersPacket(
- 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
- GetResponseHeaders("200"), nullptr));
- const char kRespData3[] = "3";
- unpartitioned_mock_quic_data.AddRead(
- ASYNC, server_maker1.MakeDataPacket(
- 6, GetNthClientInitiatedBidirectionalStreamId(2), true,
- ConstructDataFrame(kRespData3)));
- unpartitioned_mock_quic_data.AddWrite(
- SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
-
- unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
-
- // Reads and writes for the partitioned case, where two sockets are used.
-
- MockQuicData partitioned_mock_quic_data1(version_);
- QuicTestPacketMaker client_maker2(
- version_,
- quic::QuicUtils::CreateRandomConnectionId(
- context_.random_generator()),
- context_.clock(), kDefaultServerHostName,
- quic::Perspective::IS_CLIENT,
- /*client_priority_uses_incremental=*/true,
- /*use_priority_header=*/true);
- QuicTestPacketMaker server_maker2(
- version_,
- quic::QuicUtils::CreateRandomConnectionId(
- context_.random_generator()),
- context_.clock(), kDefaultServerHostName,
- quic::Perspective::IS_SERVER,
- /*client_priority_uses_incremental=*/false,
- /*use_priority_header=*/false);
-
- int packet_num2 = 1;
- partitioned_mock_quic_data1.AddWrite(
- SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(packet_num2++));
-
- partitioned_mock_quic_data1.AddWrite(
- SYNCHRONOUS,
- client_maker2.MakeRequestHeadersPacket(
- packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
- true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
- partitioned_mock_quic_data1.AddRead(
- ASYNC, server_maker2.MakeResponseHeadersPacket(
- 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
- GetResponseHeaders("200"), nullptr));
- partitioned_mock_quic_data1.AddRead(
- ASYNC, server_maker2.MakeDataPacket(
- 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
- ConstructDataFrame(kRespData1)));
- partitioned_mock_quic_data1.AddWrite(
- SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
-
- partitioned_mock_quic_data1.AddWrite(
- SYNCHRONOUS,
- client_maker2.MakeRequestHeadersPacket(
- packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
- true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
- partitioned_mock_quic_data1.AddRead(
- ASYNC, server_maker2.MakeResponseHeadersPacket(
- 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
- GetResponseHeaders("200"), nullptr));
- partitioned_mock_quic_data1.AddRead(
- ASYNC, server_maker2.MakeDataPacket(
- 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
- ConstructDataFrame(kRespData3)));
- partitioned_mock_quic_data1.AddWrite(
- SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
-
- partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
-
- MockQuicData partitioned_mock_quic_data2(version_);
- QuicTestPacketMaker client_maker3(
- version_,
- quic::QuicUtils::CreateRandomConnectionId(
- context_.random_generator()),
- context_.clock(), kDefaultServerHostName,
- quic::Perspective::IS_CLIENT,
- /*client_priority_uses_incremental=*/true,
- /*use_priority_header=*/true);
- QuicTestPacketMaker server_maker3(
- version_,
- quic::QuicUtils::CreateRandomConnectionId(
- context_.random_generator()),
- context_.clock(), kDefaultServerHostName,
- quic::Perspective::IS_SERVER,
- /*client_priority_uses_incremental=*/false,
- /*use_priority_header=*/false);
-
- int packet_num3 = 1;
- partitioned_mock_quic_data2.AddWrite(
- SYNCHRONOUS, client_maker3.MakeInitialSettingsPacket(packet_num3++));
-
- partitioned_mock_quic_data2.AddWrite(
- SYNCHRONOUS,
- client_maker3.MakeRequestHeadersPacket(
- packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
- true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
- GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
- partitioned_mock_quic_data2.AddRead(
- ASYNC, server_maker3.MakeResponseHeadersPacket(
- 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
- GetResponseHeaders("200"), nullptr));
- partitioned_mock_quic_data2.AddRead(
- ASYNC, server_maker3.MakeDataPacket(
- 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
- ConstructDataFrame(kRespData2)));
- partitioned_mock_quic_data2.AddWrite(
- SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
-
- partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
-
- if (partition_connections) {
- partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
- partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
- } else {
- unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
- }
-
- CreateSession();
-
- TestCompletionCallback callback;
- HttpRequestInfo request1;
- request1.method = "GET";
- request1.url = GURL(url1);
- request1.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- request1.network_isolation_key = network_isolation_key1;
- request1.network_anonymization_key = network_anonymization_key1;
- HttpNetworkTransaction trans1(LOWEST, session_.get());
- int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
- EXPECT_THAT(callback.GetResult(rv), IsOk());
- std::string response_data1;
- EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
- EXPECT_EQ(kRespData1, response_data1);
-
- HttpRequestInfo request2;
- request2.method = "GET";
- request2.url = GURL(url2);
- request2.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- request2.network_isolation_key = network_isolation_key2;
- request2.network_anonymization_key = network_anonymization_key2;
- HttpNetworkTransaction trans2(LOWEST, session_.get());
- rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
- EXPECT_THAT(callback.GetResult(rv), IsOk());
- std::string response_data2;
- EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
- EXPECT_EQ(kRespData2, response_data2);
-
- HttpRequestInfo request3;
- request3.method = "GET";
- request3.url = GURL(url3);
- request3.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- request3.network_isolation_key = network_isolation_key1;
- request3.network_anonymization_key = network_anonymization_key1;
-
- HttpNetworkTransaction trans3(LOWEST, session_.get());
- rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
- EXPECT_THAT(callback.GetResult(rv), IsOk());
- std::string response_data3;
- EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
- EXPECT_EQ(kRespData3, response_data3);
-
- if (partition_connections) {
- EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
- EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
- EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
- EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
- } else {
- EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
- EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
- }
+ if (partition_connections) {
+ EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
+ EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
+ EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
+ EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
+ } else {
+ EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
+ EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
}
}
}