#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "net/http/http_stream_factory.h"
#include <stdint.h>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "net/base/completion_once_callback.h"
#include "net/base/features.h"
#include "net/base/net_errors.h"
#include "net/base/network_isolation_key.h"
#include "net/base/port_util.h"
#include "net/base/privacy_mode.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/proxy_string_util.h"
#include "net/base/schemeful_site.h"
#include "net/base/session_usage.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_proxy_delegate.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/bidirectional_stream_impl.h"
#include "net/http/bidirectional_stream_request_info.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_session_peer.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_proxy_connect_job.h"
#include "net/http/http_request_info.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_stream.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/quic/mock_crypto_client_stream_factory.h"
#include "net/quic/mock_quic_context.h"
#include "net/quic/mock_quic_data.h"
#include "net/quic/quic_http_utils.h"
#include "net/quic/quic_session_pool_peer.h"
#include "net/quic/quic_test_packet_maker.h"
#include "net/quic/quic_test_packet_printer.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/connect_job.h"
#include "net/socket/mock_client_socket_pool_manager.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/socks_connect_job.h"
#include "net/socket/ssl_connect_job.h"
#include "net/socket/transport_connect_job.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_test_util_common.h"
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "net/test/test_with_task_environment.h"
#include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_server_id.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/websockets/websocket_handshake_stream_base.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"
Contains;
ElementsAre;
IsEmpty;
Key;
SizeIs;
IsError;
IsOk;
namespace base {
class Value;
}
namespace net {
class BidirectionalStreamImpl;
class WebSocketEndpointLockManager;
}
namespace net::test {
namespace {
class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase { … };
class MockHttpStreamFactoryForPreconnect : public HttpStreamFactory { … };
class StreamRequestWaiter : public HttpStreamRequest::Delegate { … };
class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream { … };
class WebSocketStreamCreateHelper
: public WebSocketHandshakeStreamBase::CreateHelper { … };
struct TestCase { … };
TestCase kTests[] = …;
void PreconnectHelperForURL(int num_streams,
const GURL& url,
NetworkAnonymizationKey network_anonymization_key,
SecureDnsPolicy secure_dns_policy,
HttpNetworkSession* session) { … }
void PreconnectHelper(const TestCase& test, HttpNetworkSession* session) { … }
ClientSocketPool::GroupId GetGroupId(const TestCase& test) { … }
class CapturePreconnectsTransportSocketPool : public TransportClientSocketPool { … };
HttpStreamFactoryTest;
TEST_F(HttpStreamFactoryTest, PreconnectDirect) { … }
TEST_F(HttpStreamFactoryTest, PreconnectHttpProxy) { … }
TEST_F(HttpStreamFactoryTest, PreconnectSocksProxy) { … }
TEST_F(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { … }
TEST_F(HttpStreamFactoryTest, PreconnectUnsafePort) { … }
TEST_F(HttpStreamFactoryTest, PreconnectInvalidUrls) { … }
TEST_F(HttpStreamFactoryTest, PreconnectNetworkIsolationKey) { … }
TEST_F(HttpStreamFactoryTest, PreconnectDisableSecureDns) { … }
TEST_F(HttpStreamFactoryTest, JobNotifiesProxy) { … }
TEST_F(HttpStreamFactoryTest, NoProxyFallbackOnTunnelFail) { … }
const int quic_proxy_test_mock_errors[] = …;
TEST_F(HttpStreamFactoryTest, QuicProxyMarkedAsBad) { … }
class TestBidirectionalDelegate : public BidirectionalStreamImpl::Delegate { … };
}
TEST_F(HttpStreamFactoryTest, UsePreConnectIfNoZeroRTT) { … }
namespace {
int GetSocketPoolGroupCount(ClientSocketPool* pool) { … }
int GetSpdySessionCount(HttpNetworkSession* session) { … }
int GetHandedOutSocketCount(ClientSocketPool* pool) { … }
int GetQuicSessionCount(HttpNetworkSession* session) { … }
TEST_F(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { … }
TEST_F(HttpStreamFactoryTest, DisableSecureDnsUsesDifferentSocketPoolGroup) { … }
TEST_F(HttpStreamFactoryTest, GetLoadState) { … }
TEST_F(HttpStreamFactoryTest, RequestHttpStream) { … }
TEST_F(HttpStreamFactoryTest, ReprioritizeAfterStreamReceived) { … }
TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { … }
TEST_F(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { … }
TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) { … }
TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) { … }
TEST_F(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) { … }
TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpsURL) { … }
TEST_F(HttpStreamFactoryTest, RequestSpdyHttpStreamHttpURL) { … }
TEST_F(HttpStreamFactoryTest,
RequestSpdyHttpStreamHttpURLWithNetworkAnonymizationKey) { … }
TEST_F(HttpStreamFactoryTest, NewSpdySessionCloseIdleH2Sockets) { … }
TEST_F(HttpStreamFactoryTest, TwoSpdyConnects) { … }
TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImpl) { … }
class HttpStreamFactoryQuicTest
: public TestWithTaskEnvironment,
public ::testing::WithParamInterface<quic::ParsedQuicVersion> { … };
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(HttpStreamFactoryQuicTest, RequestHttpStreamOverQuicProxy) { … }
TEST_P(HttpStreamFactoryQuicTest, RequestHttpStreamOverTwoQuicProxies) { … }
class HttpStreamFactoryBidirectionalQuicTest
: public TestWithTaskEnvironment,
public ::testing::WithParamInterface<quic::ParsedQuicVersion> { … };
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(HttpStreamFactoryBidirectionalQuicTest,
RequestBidirectionalStreamImplQuicAlternative) { … }
TEST_P(HttpStreamFactoryBidirectionalQuicTest,
RequestBidirectionalStreamImplHttpJobFailsQuicJobSucceeds) { … }
TEST_F(HttpStreamFactoryTest, RequestBidirectionalStreamImplFailure) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(HttpStreamFactoryTest, Tag) {
SpdySessionDependencies session_deps;
auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
auto* socket_factory_ptr = socket_factory.get();
session_deps.socket_factory = std::move(socket_factory);
MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data(base::span_from_ref(mock_read),
base::span<MockWrite>());
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data2(base::span_from_ref(mock_read2),
base::span<MockWrite>());
socket_data2.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ssl_socket_data.next_proto = kProtoHTTP2;
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
ssl_socket_data2.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ssl_socket_data2.next_proto = kProtoHTTP2;
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
std::unique_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
HttpRequestInfo request_info1;
request_info1.method = "GET";
request_info1.url = GURL("https://example.org");
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
request_info1.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(getuid(), 0x87654321);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
request_info2.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
StreamRequestWaiter waiter1;
std::unique_ptr<HttpStreamRequest> request1(
session->http_stream_factory()->RequestStream(
request_info1, DEFAULT_PRIORITY, {},
&waiter1, true,
true, NetLogWithSource()));
waiter1.WaitForStream();
EXPECT_TRUE(waiter1.stream_done());
EXPECT_TRUE(nullptr == waiter1.websocket_stream());
ASSERT_TRUE(nullptr != waiter1.stream());
EXPECT_EQ(1, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(1,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_TRUE(tag1 == socket_factory_ptr->GetLastProducedTCPSocket()->tag());
EXPECT_TRUE(socket_factory_ptr->GetLastProducedTCPSocket()
->tagged_before_connected());
StreamRequestWaiter waiter2;
std::unique_ptr<HttpStreamRequest> request2(
session->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter2, true,
true, NetLogWithSource()));
waiter2.WaitForStream();
EXPECT_TRUE(waiter2.stream_done());
EXPECT_TRUE(nullptr == waiter2.websocket_stream());
ASSERT_TRUE(nullptr != waiter2.stream());
EXPECT_EQ(2, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(2,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_TRUE(tag2 == socket_factory_ptr->GetLastProducedTCPSocket()->tag());
EXPECT_TRUE(socket_factory_ptr->GetLastProducedTCPSocket()
->tagged_before_connected());
StreamRequestWaiter waiter3;
std::unique_ptr<HttpStreamRequest> request3(
session->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter3, true,
true, NetLogWithSource()));
waiter3.WaitForStream();
EXPECT_TRUE(waiter3.stream_done());
EXPECT_TRUE(nullptr == waiter3.websocket_stream());
ASSERT_TRUE(nullptr != waiter3.stream());
EXPECT_EQ(2, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(2,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
}
TEST_P(HttpStreamFactoryBidirectionalQuicTest, Tag) {
MockQuicData mock_quic_data(version());
spdy::SpdyPriority priority =
ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
size_t spdy_headers_frame_length;
int packet_num = 1;
mock_quic_data.AddWrite(
SYNCHRONOUS,
client_packet_maker().MakeInitialSettingsPacket(packet_num++));
mock_quic_data.AddWrite(
SYNCHRONOUS,
client_packet_maker().MakeRequestHeadersPacket(
packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
true, priority,
client_packet_maker().GetRequestHeaders("GET", "https", "/"),
&spdy_headers_frame_length));
size_t spdy_response_headers_frame_length;
mock_quic_data.AddRead(
ASYNC, server_packet_maker().MakeResponseHeadersPacket(
1, GetNthClientInitiatedBidirectionalStreamId(0),
true, server_packet_maker().GetResponseHeaders("200"),
&spdy_response_headers_frame_length));
mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
mock_quic_data.AddSocketDataToFactory(&socket_factory());
client_packet_maker().Reset();
MockQuicData mock_quic_data2(version());
packet_num = 1;
mock_quic_data2.AddWrite(
SYNCHRONOUS,
client_packet_maker().MakeInitialSettingsPacket(packet_num++));
mock_quic_data2.AddWrite(
SYNCHRONOUS,
client_packet_maker().MakeRequestHeadersPacket(
packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
true, priority,
client_packet_maker().GetRequestHeaders("GET", "https", "/"),
&spdy_headers_frame_length));
mock_quic_data2.AddRead(
ASYNC, server_packet_maker().MakeResponseHeadersPacket(
1, GetNthClientInitiatedBidirectionalStreamId(0),
true, server_packet_maker().GetResponseHeaders("200"),
&spdy_response_headers_frame_length));
mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
mock_quic_data2.AddSocketDataToFactory(&socket_factory());
auto hanging_data = std::make_unique<StaticSocketDataProvider>();
MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
hanging_data->set_connect_data(hanging_connect);
socket_factory().AddSocketDataProvider(hanging_data.get());
SSLSocketDataProvider ssl_data(ASYNC, OK);
socket_factory().AddSSLSocketDataProvider(&ssl_data);
Initialize();
AddQuicAlternativeService();
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
HttpRequestInfo request_info1;
request_info1.method = "GET";
request_info1.url = default_url_;
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
request_info1.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(getuid(), 0x87654321);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
request_info2.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
StreamRequestWaiter waiter1;
std::unique_ptr<HttpStreamRequest> request1(
session()->http_stream_factory()->RequestStream(
request_info1, DEFAULT_PRIORITY, {},
&waiter1, true,
true, NetLogWithSource()));
waiter1.WaitForStream();
EXPECT_TRUE(waiter1.stream_done());
EXPECT_TRUE(nullptr == waiter1.websocket_stream());
ASSERT_TRUE(nullptr != waiter1.stream());
EXPECT_EQ(kProtoQUIC, request1->negotiated_protocol());
EXPECT_EQ(1, GetQuicSessionCount(session()));
EXPECT_TRUE(tag1 == socket_factory().GetLastProducedUDPSocket()->tag());
EXPECT_TRUE(socket_factory()
.GetLastProducedUDPSocket()
->tagged_before_data_transferred());
StreamRequestWaiter waiter2;
std::unique_ptr<HttpStreamRequest> request2(
session()->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter2, true,
true, NetLogWithSource()));
waiter2.WaitForStream();
EXPECT_TRUE(waiter2.stream_done());
EXPECT_TRUE(nullptr == waiter2.websocket_stream());
ASSERT_TRUE(nullptr != waiter2.stream());
EXPECT_EQ(kProtoQUIC, request2->negotiated_protocol());
EXPECT_EQ(2, GetQuicSessionCount(session()));
EXPECT_TRUE(tag2 == socket_factory().GetLastProducedUDPSocket()->tag());
EXPECT_TRUE(socket_factory()
.GetLastProducedUDPSocket()
->tagged_before_data_transferred());
StreamRequestWaiter waiter3;
std::unique_ptr<HttpStreamRequest> request3(
session()->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter3, true,
true, NetLogWithSource()));
waiter3.WaitForStream();
EXPECT_TRUE(waiter3.stream_done());
EXPECT_TRUE(nullptr == waiter3.websocket_stream());
ASSERT_TRUE(nullptr != waiter3.stream());
EXPECT_EQ(kProtoQUIC, request3->negotiated_protocol());
EXPECT_EQ(2, GetQuicSessionCount(session()));
}
TEST_F(HttpStreamFactoryTest, ChangeSocketTag) {
SpdySessionDependencies session_deps;
auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
auto* socket_factory_ptr = socket_factory.get();
session_deps.socket_factory = std::move(socket_factory);
MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data(base::span_from_ref(mock_read),
base::span<MockWrite>());
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data2(base::span_from_ref(mock_read2),
base::span<MockWrite>());
socket_data2.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ssl_socket_data.next_proto = kProtoHTTP2;
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
ssl_socket_data2.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ssl_socket_data2.next_proto = kProtoHTTP2;
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
std::unique_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
HttpRequestInfo request_info1;
request_info1.method = "GET";
request_info1.url = GURL("https://www.example.org");
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
request_info1.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(getuid(), 0x87654321);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
request_info2.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
HttpRequestInfo request_info3 = request_info1;
request_info3.url = GURL("https://foo.example.org");
request_info3.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
StreamRequestWaiter waiter1;
std::unique_ptr<HttpStreamRequest> request1(
session->http_stream_factory()->RequestStream(
request_info1, DEFAULT_PRIORITY, {},
&waiter1, true,
true, NetLogWithSource()));
waiter1.WaitForStream();
EXPECT_TRUE(waiter1.stream_done());
EXPECT_FALSE(waiter1.websocket_stream());
ASSERT_TRUE(waiter1.stream());
EXPECT_EQ(1, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(1,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
MockTaggingStreamSocket* socket =
socket_factory_ptr->GetLastProducedTCPSocket();
EXPECT_TRUE(tag1 == socket->tag());
EXPECT_TRUE(socket->tagged_before_connected());
StreamRequestWaiter waiter2;
std::unique_ptr<HttpStreamRequest> request2(
session->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter2, true,
true, NetLogWithSource()));
waiter2.WaitForStream();
EXPECT_TRUE(waiter2.stream_done());
EXPECT_FALSE(waiter2.websocket_stream());
ASSERT_TRUE(waiter2.stream());
EXPECT_EQ(1, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(1,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(socket, socket_factory_ptr->GetLastProducedTCPSocket());
EXPECT_TRUE(tag2 == socket->tag());
EXPECT_FALSE(socket->tagged_before_connected());
TestCompletionCallback callback1;
waiter1.stream()->RegisterRequest(&request_info1);
EXPECT_EQ(ERR_FAILED, waiter1.stream()->InitializeStream(
false, DEFAULT_PRIORITY,
NetLogWithSource(), callback1.callback()));
StreamRequestWaiter waiter3;
std::unique_ptr<HttpStreamRequest> request3(
session->http_stream_factory()->RequestStream(
request_info3, DEFAULT_PRIORITY, {},
&waiter3, true,
true, NetLogWithSource()));
waiter3.WaitForStream();
EXPECT_TRUE(waiter3.stream_done());
EXPECT_FALSE(waiter3.websocket_stream());
ASSERT_TRUE(waiter3.stream());
EXPECT_EQ(1, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(1,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(socket, socket_factory_ptr->GetLastProducedTCPSocket());
EXPECT_TRUE(tag1 == socket->tag());
EXPECT_FALSE(socket->tagged_before_connected());
TestCompletionCallback callback3;
waiter3.stream()->RegisterRequest(&request_info3);
EXPECT_EQ(OK, waiter3.stream()->InitializeStream(
false, DEFAULT_PRIORITY,
NetLogWithSource(), callback3.callback()));
StreamRequestWaiter waiter4;
std::unique_ptr<HttpStreamRequest> request4(
session->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter4, true,
true, NetLogWithSource()));
waiter4.WaitForStream();
EXPECT_TRUE(waiter4.stream_done());
EXPECT_FALSE(waiter4.websocket_stream());
ASSERT_TRUE(waiter4.stream());
EXPECT_EQ(2, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(2,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
MockTaggingStreamSocket* socket2 =
socket_factory_ptr->GetLastProducedTCPSocket();
EXPECT_NE(socket, socket2);
EXPECT_TRUE(tag2 == socket2->tag());
EXPECT_TRUE(socket2->tagged_before_connected());
EXPECT_TRUE(tag1 == socket->tag());
waiter3.stream()->Close( true);
}
TEST_F(HttpStreamFactoryTest, ChangeSocketTagAvoidOverwrite) {
SpdySessionDependencies session_deps;
auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
auto* socket_factory_ptr = socket_factory.get();
session_deps.socket_factory = std::move(socket_factory);
MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data(base::span_from_ref(mock_read),
base::span<MockWrite>());
socket_data.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data);
MockRead mock_read2(SYNCHRONOUS, ERR_IO_PENDING);
SequencedSocketData socket_data2(base::span_from_ref(mock_read2),
base::span<MockWrite>());
socket_data2.set_connect_data(MockConnect(ASYNC, OK));
session_deps.socket_factory->AddSocketDataProvider(&socket_data2);
SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
ssl_socket_data.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ssl_socket_data.next_proto = kProtoHTTP2;
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
SSLSocketDataProvider ssl_socket_data2(ASYNC, OK);
ssl_socket_data2.ssl_info.cert =
ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
ssl_socket_data2.next_proto = kProtoHTTP2;
session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data2);
std::unique_ptr<HttpNetworkSession> session(
SpdySessionDependencies::SpdyCreateSession(&session_deps));
SocketTag tag1(SocketTag::UNSET_UID, 2);
HttpRequestInfo request_info1;
request_info1.method = "GET";
request_info1.url = GURL("https://www.example.org");
request_info1.load_flags = 0;
request_info1.socket_tag = tag1;
request_info1.traffic_annotation =
MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
SocketTag tag2(SocketTag::UNSET_UID, 1);
HttpRequestInfo request_info2 = request_info1;
request_info2.socket_tag = tag2;
HttpRequestInfo request_info3 = request_info1;
SocketTag tag3(SocketTag::UNSET_UID, 3);
request_info3.socket_tag = tag3;
HttpRequestInfo request_info4 = request_info1;
request_info4.socket_tag = tag3;
request_info4.url = GURL("https://foo.example.org");
StreamRequestWaiter waiter1;
std::unique_ptr<HttpStreamRequest> request1(
session->http_stream_factory()->RequestStream(
request_info1, DEFAULT_PRIORITY, {},
&waiter1, true,
true, NetLogWithSource()));
waiter1.WaitForStream();
EXPECT_TRUE(waiter1.stream_done());
EXPECT_FALSE(waiter1.websocket_stream());
ASSERT_TRUE(waiter1.stream());
EXPECT_EQ(1, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(1,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
MockTaggingStreamSocket* socket =
socket_factory_ptr->GetLastProducedTCPSocket();
EXPECT_TRUE(tag1 == socket->tag());
EXPECT_TRUE(socket->tagged_before_connected());
TestCompletionCallback callback1;
waiter1.stream()->RegisterRequest(&request_info1);
EXPECT_EQ(OK, waiter1.stream()->InitializeStream(
false, DEFAULT_PRIORITY,
NetLogWithSource(), callback1.callback()));
StreamRequestWaiter waiter2;
std::unique_ptr<HttpStreamRequest> request2(
session->http_stream_factory()->RequestStream(
request_info2, DEFAULT_PRIORITY, {},
&waiter2, true,
true, NetLogWithSource()));
waiter2.WaitForStream();
EXPECT_TRUE(waiter2.stream_done());
EXPECT_FALSE(waiter2.websocket_stream());
ASSERT_TRUE(waiter2.stream());
EXPECT_EQ(2, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(2,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
MockTaggingStreamSocket* socket2 =
socket_factory_ptr->GetLastProducedTCPSocket();
EXPECT_NE(socket, socket2);
EXPECT_TRUE(tag2 == socket2->tag());
EXPECT_TRUE(socket2->tagged_before_connected());
EXPECT_TRUE(tag1 == socket->tag());
TestCompletionCallback callback2;
waiter2.stream()->RegisterRequest(&request_info2);
EXPECT_EQ(OK, waiter2.stream()->InitializeStream(
false, DEFAULT_PRIORITY,
NetLogWithSource(), callback2.callback()));
waiter1.stream()->Close( true);
StreamRequestWaiter waiter3;
std::unique_ptr<HttpStreamRequest> request3(
session->http_stream_factory()->RequestStream(
request_info3, DEFAULT_PRIORITY, {},
&waiter3, true,
true, NetLogWithSource()));
waiter3.WaitForStream();
EXPECT_TRUE(waiter3.stream_done());
EXPECT_FALSE(waiter3.websocket_stream());
ASSERT_TRUE(waiter3.stream());
EXPECT_EQ(2, GetSpdySessionCount(session.get()));
EXPECT_EQ(1,
GetSocketPoolGroupCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(2,
GetHandedOutSocketCount(session->GetSocketPool(
HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyChain::Direct())));
EXPECT_EQ(socket2, socket_factory_ptr->GetLastProducedTCPSocket());
EXPECT_TRUE(tag3 == socket->tag());
EXPECT_FALSE(socket->tagged_before_connected());
waiter2.stream()->Close( true);
StreamRequestWaiter waiter4;
std::unique_ptr<HttpStreamRequest> request4(
session->http_stream_factory()->RequestStream(
request_info4, DEFAULT_PRIORITY, {},
&waiter4, true,
true, NetLogWithSource()));
waiter4.WaitForStream();
EXPECT_TRUE(waiter4.stream_done());
EXPECT_FALSE(waiter4.websocket_stream());
ASSERT_TRUE(waiter4.stream());
EXPECT_EQ(socket2, socket_factory_ptr->GetLastProducedTCPSocket());
}
#endif
TEST_F(HttpStreamFactoryTest, MultiIPAliases) { … }
TEST_F(HttpStreamFactoryTest, SpdyIPPoolingWithDnsAliases) { … }
TEST_P(HttpStreamFactoryBidirectionalQuicTest, QuicIPPoolingWithDnsAliases) { … }
class ProcessAlternativeServicesTest : public TestWithTaskEnvironment { … };
TEST_F(ProcessAlternativeServicesTest, ProcessEmptyAltSvc) { … }
TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcClear) { … }
TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcQuicIetf) { … }
TEST_F(ProcessAlternativeServicesTest, ProcessAltSvcHttp2) { … }
}
}