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/http/http_stream_key.h"
6
7 #include "base/test/scoped_feature_list.h"
8 #include "net/base/features.h"
9 #include "net/base/network_anonymization_key.h"
10 #include "net/base/privacy_mode.h"
11 #include "net/dns/public/secure_dns_policy.h"
12 #include "net/socket/socket_tag.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "url/gurl.h"
15 #include "url/scheme_host_port.h"
16
17 namespace net {
18
19 namespace {
20
21 static const url::SchemeHostPort kHost("https", "www.example.com", 443);
22
23 } // namespace
24
25 // These tests are similar to SpdySessionKeyTest. Note that we don't support
26 // non-null SocketTag.
27
TEST(HttpStreamKeyTest,Equality)28 TEST(HttpStreamKeyTest, Equality) {
29 HttpStreamKey key(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
30 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
31 /*disable_cert_network_fetches=*/true);
32
33 EXPECT_EQ(key,
34 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
35 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
36 /*disable_cert_network_fetches=*/true));
37
38 EXPECT_NE(key,
39 HttpStreamKey(url::SchemeHostPort("https", "othersite", 443),
40 PRIVACY_MODE_DISABLED, SocketTag(),
41 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
42 /*disable_cert_network_fetches=*/true));
43
44 EXPECT_NE(key,
45 HttpStreamKey(kHost, PRIVACY_MODE_ENABLED, SocketTag(),
46 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
47 /*disable_cert_network_fetches=*/true));
48
49 HttpStreamKey anonymized_key(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
50 NetworkAnonymizationKey::CreateSameSite(
51 SchemefulSite(GURL("http://a.test/"))),
52 SecureDnsPolicy::kAllow,
53 /*disable_cert_network_fetches=*/true);
54 if (NetworkAnonymizationKey::IsPartitioningEnabled()) {
55 EXPECT_NE(key, anonymized_key);
56 } else {
57 EXPECT_EQ(key, anonymized_key);
58 }
59
60 EXPECT_NE(key,
61 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
62 NetworkAnonymizationKey(), SecureDnsPolicy::kDisable,
63 /*disable_cert_network_fetches=*/true));
64
65 EXPECT_NE(key,
66 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
67 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
68 /*disable_cert_network_fetches=*/false));
69 }
70
TEST(HttpStreamKeyTest,OrderedSet)71 TEST(HttpStreamKeyTest, OrderedSet) {
72 const std::vector<HttpStreamKey> stream_keys = {
73 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
74 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
75 /*disable_cert_network_fetches=*/true),
76 HttpStreamKey(url::SchemeHostPort("https", "othersite", 443),
77 PRIVACY_MODE_DISABLED, SocketTag(),
78 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
79 /*disable_cert_network_fetches=*/true),
80 HttpStreamKey(kHost, PRIVACY_MODE_ENABLED, SocketTag(),
81 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
82 /*disable_cert_network_fetches=*/true),
83 // This has different network_anonymization_key, but it's the same as the
84 // first one when anonymization is disabled.
85 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
86 NetworkAnonymizationKey::CreateSameSite(
87 SchemefulSite(GURL("http://a.test/"))),
88 SecureDnsPolicy::kAllow,
89 /*disable_cert_network_fetches=*/true),
90 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
91 NetworkAnonymizationKey(), SecureDnsPolicy::kDisable,
92 /*disable_cert_network_fetches=*/true),
93 HttpStreamKey(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
94 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
95 /*disable_cert_network_fetches=*/false),
96 };
97
98 const std::set<HttpStreamKey> key_set(stream_keys.begin(), stream_keys.end());
99 const size_t expected_size = NetworkAnonymizationKey::IsPartitioningEnabled()
100 ? stream_keys.size()
101 : stream_keys.size() - 1;
102 ASSERT_EQ(key_set.size(), expected_size);
103 }
104
TEST(HttpStreamKeyTest,Anonymization)105 TEST(HttpStreamKeyTest, Anonymization) {
106 for (const bool enabled : {false, true}) {
107 SCOPED_TRACE(enabled ? "Anonymization enabled" : "Anonymization disabled");
108
109 base::test::ScopedFeatureList feature_list;
110 if (enabled) {
111 feature_list.InitAndEnableFeature(
112 features::kPartitionConnectionsByNetworkIsolationKey);
113 } else {
114 feature_list.InitAndDisableFeature(
115 features::kPartitionConnectionsByNetworkIsolationKey);
116 }
117
118 const HttpStreamKey key(kHost, PRIVACY_MODE_DISABLED, SocketTag(),
119 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
120 /*disable_cert_network_fetches=*/true);
121
122 const HttpStreamKey anonymized_key(
123 kHost, PRIVACY_MODE_DISABLED, SocketTag(),
124 NetworkAnonymizationKey::CreateSameSite(
125 SchemefulSite(GURL("http://a.test/"))),
126 SecureDnsPolicy::kAllow,
127 /*disable_cert_network_fetches=*/true);
128
129 if (enabled) {
130 EXPECT_NE(key, anonymized_key);
131 } else {
132 EXPECT_EQ(key, anonymized_key);
133 }
134 }
135 }
136
TEST(HttpStreamKeyTest,ToSpdySessionKey)137 TEST(HttpStreamKeyTest, ToSpdySessionKey) {
138 const url::SchemeHostPort kHttpHost("http", "example.com", 80);
139 const url::SchemeHostPort kHttpsHost("https", "example.com", 443);
140
141 SpdySessionKey http_key =
142 HttpStreamKey(kHttpHost, PRIVACY_MODE_DISABLED, SocketTag(),
143 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
144 /*disable_cert_network_fetches=*/true)
145 .CalculateSpdySessionKey();
146 ASSERT_TRUE(http_key.host_port_pair().IsEmpty());
147
148 SpdySessionKey https_key =
149 HttpStreamKey(kHttpsHost, PRIVACY_MODE_DISABLED, SocketTag(),
150 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
151 /*disable_cert_network_fetches=*/true)
152 .CalculateSpdySessionKey();
153 ASSERT_EQ(https_key,
154 SpdySessionKey(HostPortPair::FromSchemeHostPort(kHttpsHost),
155 PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
156 SessionUsage::kDestination, SocketTag(),
157 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
158 /*disable_cert_verification_network_fetches=*/true));
159 }
160
TEST(HttpStreamKeyTest,CalculateQuicSessionAliasKey)161 TEST(HttpStreamKeyTest, CalculateQuicSessionAliasKey) {
162 const url::SchemeHostPort kHttpHost("http", "example.com", 80);
163 const url::SchemeHostPort kHttpsHost("https", "example.com", 443);
164 const url::SchemeHostPort kHttpsAliasHost("https", "alt.example.com", 443);
165
166 QuicSessionAliasKey http_key =
167 HttpStreamKey(kHttpHost, PRIVACY_MODE_DISABLED, SocketTag(),
168 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
169 /*disable_cert_network_fetches=*/true)
170 .CalculateQuicSessionAliasKey();
171 ASSERT_TRUE(http_key.session_key().host().empty());
172 ASSERT_FALSE(http_key.destination().IsValid());
173
174 QuicSessionAliasKey https_key =
175 HttpStreamKey(kHttpsHost, PRIVACY_MODE_DISABLED, SocketTag(),
176 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
177 /*disable_cert_network_fetches=*/true)
178 .CalculateQuicSessionAliasKey();
179 ASSERT_EQ(https_key.session_key(),
180 QuicSessionKey(HostPortPair::FromSchemeHostPort(kHttpsHost),
181 PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
182 SessionUsage::kDestination, SocketTag(),
183 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
184 /*require_dns_https_alpn=*/false));
185 ASSERT_EQ(https_key.destination(), kHttpsHost);
186
187 QuicSessionAliasKey different_origin_key =
188 HttpStreamKey(kHttpsHost, PRIVACY_MODE_DISABLED, SocketTag(),
189 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
190 /*disable_cert_network_fetches=*/true)
191 .CalculateQuicSessionAliasKey(kHttpsAliasHost);
192 ASSERT_EQ(different_origin_key.session_key(),
193 QuicSessionKey(HostPortPair::FromSchemeHostPort(kHttpsHost),
194 PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
195 SessionUsage::kDestination, SocketTag(),
196 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
197 /*require_dns_https_alpn=*/false));
198 ASSERT_EQ(different_origin_key.destination(), kHttpsAliasHost);
199 }
200
201 } // namespace net
202