1 // Copyright 2013 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 <memory>
6 #include <ostream>
7 #include <utility>
8 #include <vector>
9
10 #include "base/compiler_specific.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "net/base/completion_once_callback.h"
16 #include "net/base/elements_upload_data_stream.h"
17 #include "net/base/ip_address.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/base/upload_bytes_element_reader.h"
20 #include "net/base/upload_data_stream.h"
21 #include "net/cert/ct_policy_enforcer.h"
22 #include "net/cert/mock_cert_verifier.h"
23 #include "net/cert/multi_log_ct_verifier.h"
24 #include "net/dns/mapped_host_resolver.h"
25 #include "net/dns/mock_host_resolver.h"
26 #include "net/http/http_auth_handler_factory.h"
27 #include "net/http/http_network_session.h"
28 #include "net/http/http_network_transaction.h"
29 #include "net/http/http_server_properties.h"
30 #include "net/http/http_transaction_test_util.h"
31 #include "net/http/transport_security_state.h"
32 #include "net/log/net_log_with_source.h"
33 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
34 #include "net/quic/crypto_test_utils_chromium.h"
35 #include "net/quic/quic_context.h"
36 #include "net/socket/client_socket_factory.h"
37 #include "net/ssl/ssl_config_service_defaults.h"
38 #include "net/test/cert_test_util.h"
39 #include "net/test/gtest_util.h"
40 #include "net/test/test_data_directory.h"
41 #include "net/test/test_with_task_environment.h"
42 #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
43 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
44 #include "net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h"
45 #include "net/tools/quic/quic_simple_server.h"
46 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
47 #include "testing/gmock/include/gmock/gmock.h"
48 #include "testing/gtest/include/gtest/gtest.h"
49 #include "testing/platform_test.h"
50
51 namespace net {
52
53 using test::IsOk;
54
55 namespace test {
56
57 namespace {
58
59 const char kResponseBody[] = "some arbitrary response body";
60
61 // Factory for creating HttpTransactions, used by TestTransactionConsumer.
62 class TestTransactionFactory : public HttpTransactionFactory {
63 public:
TestTransactionFactory(const HttpNetworkSessionParams & session_params,const HttpNetworkSessionContext & session_context)64 explicit TestTransactionFactory(
65 const HttpNetworkSessionParams& session_params,
66 const HttpNetworkSessionContext& session_context)
67 : session_(std::make_unique<HttpNetworkSession>(session_params,
68 session_context)) {}
69
70 ~TestTransactionFactory() override = default;
71
72 // HttpTransactionFactory methods
CreateTransaction(RequestPriority priority,std::unique_ptr<HttpTransaction> * trans)73 int CreateTransaction(RequestPriority priority,
74 std::unique_ptr<HttpTransaction>* trans) override {
75 *trans = std::make_unique<HttpNetworkTransaction>(priority, session_.get());
76 return OK;
77 }
78
GetCache()79 HttpCache* GetCache() override { return nullptr; }
80
GetSession()81 HttpNetworkSession* GetSession() override { return session_.get(); }
82
83 private:
84 std::unique_ptr<HttpNetworkSession> session_;
85 };
86
87 } // namespace
88
89 class QuicEndToEndTest : public ::testing::Test, public WithTaskEnvironment {
90 protected:
QuicEndToEndTest()91 QuicEndToEndTest()
92 : host_resolver_(CreateResolverImpl()),
93 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
94 proxy_resolution_service_(
95 ConfiguredProxyResolutionService::CreateDirect()),
96 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()) {
97 request_.method = "GET";
98 request_.url = GURL("https://test.example.com/");
99 request_.load_flags = 0;
100 request_.traffic_annotation =
101 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
102
103 session_params_.enable_quic = true;
104
105 session_context_.client_socket_factory =
106 ClientSocketFactory::GetDefaultFactory();
107 session_context_.quic_context = &quic_context_;
108 session_context_.host_resolver = &host_resolver_;
109 session_context_.cert_verifier = &cert_verifier_;
110 session_context_.transport_security_state = &transport_security_state_;
111 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
112 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
113 session_context_.ssl_config_service = ssl_config_service_.get();
114 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
115 session_context_.http_server_properties = &http_server_properties_;
116
117 CertVerifyResult verify_result;
118 verify_result.verified_cert =
119 ImportCertFromFile(GetTestCertsDirectory(), "quic-chain.pem");
120 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
121 "test.example.com", verify_result,
122 OK);
123 }
124
125 // Creates a mock host resolver in which test.example.com
126 // resolves to localhost.
CreateResolverImpl()127 static std::unique_ptr<MockHostResolver> CreateResolverImpl() {
128 auto resolver = std::make_unique<MockHostResolver>();
129 resolver->rules()->AddRule("test.example.com", "127.0.0.1");
130 return resolver;
131 }
132
SetUp()133 void SetUp() override {
134 StartServer();
135
136 // Use a mapped host resolver so that request for test.example.com (port 80)
137 // reach the server running on localhost.
138 std::string map_rule =
139 "MAP test.example.com test.example.com:" +
140 base::NumberToString(server_->server_address().port());
141 EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
142
143 // To simplify the test, and avoid the race with the HTTP request, we force
144 // QUIC for these requests.
145 quic_context_.params()->origins_to_force_quic_on.insert(
146 HostPortPair::FromString("test.example.com:443"));
147
148 transaction_factory_ = std::make_unique<TestTransactionFactory>(
149 session_params_, session_context_);
150 }
151
TearDown()152 void TearDown() override {}
153
154 // Starts the QUIC server listening on a random port.
StartServer()155 void StartServer() {
156 server_address_ = IPEndPoint(IPAddress(127, 0, 0, 1), 0);
157 server_config_.SetInitialStreamFlowControlWindowToSend(
158 quic::test::kInitialStreamFlowControlWindowForTest);
159 server_config_.SetInitialSessionFlowControlWindowToSend(
160 quic::test::kInitialSessionFlowControlWindowForTest);
161 server_ = std::make_unique<QuicSimpleServer>(
162 net::test::ProofSourceForTestingChromium(), server_config_,
163 server_config_options_, AllSupportedQuicVersions(),
164 &memory_cache_backend_);
165 server_->Listen(server_address_);
166 server_address_ = server_->server_address();
167 server_->StartReading();
168 server_started_ = true;
169 }
170
171 // Adds an entry to the cache used by the QUIC server to serve
172 // responses.
AddToCache(std::string_view path,int response_code,std::string_view response_detail,std::string_view body)173 void AddToCache(std::string_view path,
174 int response_code,
175 std::string_view response_detail,
176 std::string_view body) {
177 memory_cache_backend_.AddSimpleResponse("test.example.com", path,
178 response_code, body);
179 }
180
181 // Populates |request_body_| with |length_| ASCII bytes.
GenerateBody(size_t length)182 void GenerateBody(size_t length) {
183 request_body_.clear();
184 request_body_.reserve(length);
185 for (size_t i = 0; i < length; ++i) {
186 request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
187 }
188 }
189
190 // Initializes |request_| for a post of |length| bytes.
InitializePostRequest(size_t length)191 void InitializePostRequest(size_t length) {
192 GenerateBody(length);
193 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
194 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
195 request_body_.data(), request_body_.length()));
196 upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
197 std::move(element_readers), 0);
198 request_.method = "POST";
199 request_.url = GURL("https://test.example.com/");
200 request_.upload_data_stream = upload_data_stream_.get();
201 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
202 NetLogWithSource()),
203 IsOk());
204 }
205
206 // Checks that |consumer| completed and received |status_line| and |body|.
CheckResponse(const TestTransactionConsumer & consumer,const std::string & status_line,const std::string & body)207 void CheckResponse(const TestTransactionConsumer& consumer,
208 const std::string& status_line,
209 const std::string& body) {
210 ASSERT_TRUE(consumer.is_done());
211 ASSERT_THAT(consumer.error(), IsOk());
212 EXPECT_EQ(status_line, consumer.response_info()->headers->GetStatusLine());
213 EXPECT_EQ(body, consumer.content());
214 }
215
216 QuicContext quic_context_;
217 MappedHostResolver host_resolver_;
218 MockCertVerifier cert_verifier_;
219 TransportSecurityState transport_security_state_;
220 DefaultCTPolicyEnforcer ct_policy_enforcer_;
221 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
222 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
223 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
224 HttpServerProperties http_server_properties_;
225 HttpNetworkSessionParams session_params_;
226 HttpNetworkSessionContext session_context_;
227 std::unique_ptr<TestTransactionFactory> transaction_factory_;
228 HttpRequestInfo request_;
229 std::string request_body_;
230 std::unique_ptr<UploadDataStream> upload_data_stream_;
231 std::unique_ptr<QuicSimpleServer> server_;
232 quic::QuicMemoryCacheBackend memory_cache_backend_;
233 IPEndPoint server_address_;
234 std::string server_hostname_;
235 quic::QuicConfig server_config_;
236 quic::QuicCryptoServerConfig::ConfigOptions server_config_options_;
237 bool server_started_;
238 bool strike_register_no_startup_period_ = false;
239 };
240
TEST_F(QuicEndToEndTest,LargeGetWithNoPacketLoss)241 TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
242 std::string response(10 * 1024, 'x');
243
244 AddToCache(request_.url.PathForRequest(), 200, "OK", response);
245
246 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
247 transaction_factory_.get());
248 consumer.Start(&request_, NetLogWithSource());
249
250 // Will terminate when the last consumer completes.
251 base::RunLoop().Run();
252
253 CheckResponse(consumer, "HTTP/1.1 200", response);
254 }
255
256 // crbug.com/559173
257 #if defined(THREAD_SANITIZER)
TEST_F(QuicEndToEndTest,DISABLED_LargePostWithNoPacketLoss)258 TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
259 #else
260 TEST_F(QuicEndToEndTest, LargePostWithNoPacketLoss) {
261 #endif
262 InitializePostRequest(1024 * 1024);
263
264 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
265
266 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
267 transaction_factory_.get());
268 consumer.Start(&request_, NetLogWithSource());
269
270 // Will terminate when the last consumer completes.
271 base::RunLoop().Run();
272
273 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
274 }
275
276 // crbug.com/559173
277 #if defined(THREAD_SANITIZER)
278 TEST_F(QuicEndToEndTest, DISABLED_LargePostWithPacketLoss) {
279 #else
280 TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
281 #endif
282 // FLAGS_fake_packet_loss_percentage = 30;
283 InitializePostRequest(1024 * 1024);
284
285 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
286
287 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
288 transaction_factory_.get());
289 consumer.Start(&request_, NetLogWithSource());
290
291 // Will terminate when the last consumer completes.
292 base::RunLoop().Run();
293
294 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
295 }
296
297 // crbug.com/536845
298 #if defined(THREAD_SANITIZER)
299 TEST_F(QuicEndToEndTest, DISABLED_UberTest) {
300 #else
301 TEST_F(QuicEndToEndTest, UberTest) {
302 #endif
303 // FLAGS_fake_packet_loss_percentage = 30;
304
305 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
306
307 std::vector<std::unique_ptr<TestTransactionConsumer>> consumers;
308 for (size_t i = 0; i < 100; ++i) {
309 TestTransactionConsumer* consumer = new TestTransactionConsumer(
310 DEFAULT_PRIORITY, transaction_factory_.get());
311 consumers.push_back(base::WrapUnique(consumer));
312 consumer->Start(&request_, NetLogWithSource());
313 }
314
315 // Will terminate when the last consumer completes.
316 base::RunLoop().Run();
317
318 for (const auto& consumer : consumers)
319 CheckResponse(*consumer.get(), "HTTP/1.1 200", kResponseBody);
320 }
321
322 TEST_F(QuicEndToEndTest, EnableKyber) {
323 // Enable Kyber on the client.
324 base::test::ScopedFeatureList scoped_feature_list;
325 scoped_feature_list.InitWithFeatures({features::kPostQuantumKyber}, {});
326
327 // Configure the server to only support Kyber.
328 server_->crypto_config()->set_preferred_groups(
329 {SSL_GROUP_X25519_KYBER768_DRAFT00});
330
331 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
332
333 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
334 transaction_factory_.get());
335 consumer.Start(&request_, NetLogWithSource());
336
337 // Will terminate when the last consumer completes.
338 base::RunLoop().Run();
339
340 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
341 EXPECT_EQ(consumer.response_info()->ssl_info.key_exchange_group,
342 SSL_GROUP_X25519_KYBER768_DRAFT00);
343 }
344
345 TEST_F(QuicEndToEndTest, KyberDisabled) {
346 // Disable Kyber on the client.
347 base::test::ScopedFeatureList scoped_feature_list;
348 scoped_feature_list.InitWithFeatures({}, {features::kPostQuantumKyber});
349
350 // Configure the server to only support Kyber.
351 server_->crypto_config()->set_preferred_groups(
352 {SSL_GROUP_X25519_KYBER768_DRAFT00});
353
354 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
355
356 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
357 transaction_factory_.get());
358 consumer.Start(&request_, NetLogWithSource());
359
360 // Will terminate when the last consumer completes.
361 base::RunLoop().Run();
362
363 // Connection should fail because there's no supported group in common between
364 // client and server.
365 EXPECT_EQ(consumer.error(), net::ERR_QUIC_PROTOCOL_ERROR);
366 }
367
368 } // namespace test
369 } // namespace net
370