blob: bb2c3e07be7ca9b43bb786ca700ed007e5c6ad56 [file] [log] [blame]
[email protected]50ca73e22013-09-30 00:37:501// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakjad1777e2016-04-16 00:56:425#include <memory>
rchf37ccc782016-01-31 05:13:506#include <ostream>
dchengc7eeda422015-12-26 03:56:487#include <utility>
olli.raula6df48b2a2015-11-26 07:40:228#include <vector>
9
[email protected]50ca73e22013-09-30 00:37:5010#include "base/compiler_specific.h"
danakjad1777e2016-04-16 00:56:4211#include "base/memory/ptr_util.h"
fdoraye1e050c52016-07-19 21:05:5412#include "base/run_loop.h"
[email protected]50ca73e22013-09-30 00:37:5013#include "base/strings/string_number_conversions.h"
Bence Békyd8a21fc32018-06-27 18:29:5814#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0715#include "net/base/elements_upload_data_stream.h"
martijncc5402d2016-02-16 19:08:5816#include "net/base/ip_address.h"
[email protected]50ca73e22013-09-30 00:37:5017#include "net/base/test_completion_callback.h"
18#include "net/base/upload_bytes_element_reader.h"
19#include "net/base/upload_data_stream.h"
rsleevid6de8302016-06-21 01:33:2020#include "net/cert/ct_policy_enforcer.h"
[email protected]50ca73e22013-09-30 00:37:5021#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1222#include "net/cert/multi_log_ct_verifier.h"
[email protected]50ca73e22013-09-30 00:37:5023#include "net/dns/mapped_host_resolver.h"
24#include "net/dns/mock_host_resolver.h"
25#include "net/http/http_auth_handler_factory.h"
26#include "net/http/http_network_session.h"
27#include "net/http/http_network_transaction.h"
Matt Menke609160742019-08-02 18:47:2628#include "net/http/http_server_properties.h"
[email protected]c41737d2014-05-14 07:47:1929#include "net/http/http_transaction_test_util.h"
[email protected]50ca73e22013-09-30 00:37:5030#include "net/http/transport_security_state.h"
mikecironef22f9812016-10-04 03:40:1931#include "net/log/net_log_with_source.h"
Lily Houghtonffe89daa02018-03-09 18:30:0332#include "net/proxy_resolution/proxy_resolution_service.h"
Victor Vasiliev7752898d2019-11-14 21:30:2233#include "net/quic/quic_context.h"
[email protected]50ca73e22013-09-30 00:37:5034#include "net/ssl/ssl_config_service_defaults.h"
rchf114d982015-10-21 01:34:5635#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0136#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4337#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4038#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5139#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
40#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
41#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
42#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
rche1d19cb2016-08-30 22:00:4243#include "net/tools/quic/quic_simple_server.h"
Ramin Halavatib5e433e62018-02-07 07:41:1044#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0145#include "testing/gmock/include/gmock/gmock.h"
[email protected]50ca73e22013-09-30 00:37:5046#include "testing/gtest/include/gtest/gtest.h"
47#include "testing/platform_test.h"
48
[email protected]50ca73e22013-09-30 00:37:5049namespace net {
ttuttle859dc7a2015-04-23 19:42:2950
robpercival214763f2016-07-01 23:27:0151using test::IsOk;
ttuttle859dc7a2015-04-23 19:42:2952
[email protected]50ca73e22013-09-30 00:37:5053namespace test {
54
55namespace {
56
57const char kResponseBody[] = "some arbitrary response body";
58
59// Factory for creating HttpTransactions, used by TestTransactionConsumer.
60class TestTransactionFactory : public HttpTransactionFactory {
61 public:
mmenke6ddfbea2017-05-31 21:48:4162 explicit TestTransactionFactory(
63 const HttpNetworkSession::Params& session_params,
64 const HttpNetworkSession::Context& session_context)
65 : session_(new HttpNetworkSession(session_params, session_context)) {}
[email protected]50ca73e22013-09-30 00:37:5066
dcheng67be2b1f2014-10-27 21:47:2967 ~TestTransactionFactory() override {}
[email protected]50ca73e22013-09-30 00:37:5068
69 // HttpTransactionFactory methods
dcheng67be2b1f2014-10-27 21:47:2970 int CreateTransaction(RequestPriority priority,
danakjad1777e2016-04-16 00:56:4271 std::unique_ptr<HttpTransaction>* trans) override {
dcheng4227c6d2014-08-25 23:58:1872 trans->reset(new HttpNetworkTransaction(priority, session_.get()));
[email protected]50ca73e22013-09-30 00:37:5073 return OK;
74 }
75
dcheng67be2b1f2014-10-27 21:47:2976 HttpCache* GetCache() override { return nullptr; }
[email protected]50ca73e22013-09-30 00:37:5077
Nico Weber62eb43b2019-02-11 19:00:5678 HttpNetworkSession* GetSession() override { return session_.get(); }
[email protected]50ca73e22013-09-30 00:37:5079
80 private:
danakjad1777e2016-04-16 00:56:4281 std::unique_ptr<HttpNetworkSession> session_;
[email protected]50ca73e22013-09-30 00:37:5082};
83
[email protected]50ca73e22013-09-30 00:37:5084} // namespace
85
Gabriel Charette694c3c332019-08-19 14:53:0586class QuicEndToEndTest : public ::testing::Test, public WithTaskEnvironment {
[email protected]50ca73e22013-09-30 00:37:5087 protected:
88 QuicEndToEndTest()
89 : host_resolver_impl_(CreateResolverImpl()),
dchengc7eeda422015-12-26 03:56:4890 host_resolver_(std::move(host_resolver_impl_)),
rtenneti052774e2015-11-24 21:00:1291 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]50ca73e22013-09-30 00:37:5092 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:5993 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:1194 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
[email protected]d4adc302013-09-30 03:02:3495 strike_register_no_startup_period_(false) {
[email protected]50ca73e22013-09-30 00:37:5096 request_.method = "GET";
rchf114d982015-10-21 01:34:5697 request_.url = GURL("https://test.example.com/");
[email protected]50ca73e22013-09-30 00:37:5098 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1099 request_.traffic_annotation =
100 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]50ca73e22013-09-30 00:37:50101
mmenke6ddfbea2017-05-31 21:48:41102 session_params_.enable_quic = true;
mmenke6ddfbea2017-05-31 21:48:41103
Victor Vasiliev7752898d2019-11-14 21:30:22104 session_context_.quic_context = &quic_context_;
mmenke6ddfbea2017-05-31 21:48:41105 session_context_.host_resolver = &host_resolver_;
106 session_context_.cert_verifier = &cert_verifier_;
107 session_context_.transport_security_state = &transport_security_state_;
108 session_context_.cert_transparency_verifier =
109 cert_transparency_verifier_.get();
110 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
Lily Houghton8c2f97d2018-01-22 05:06:59111 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41112 session_context_.ssl_config_service = ssl_config_service_.get();
113 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
114 session_context_.http_server_properties = &http_server_properties_;
rchf114d982015-10-21 01:34:56115
tfarinaa3dd7aa2016-02-25 08:15:44116 CertVerifyResult verify_result;
Ryan Hamiltona3ee93a72018-08-01 22:03:08117 verify_result.verified_cert =
118 ImportCertFromFile(GetTestCertsDirectory(), "quic-chain.pem");
rchf114d982015-10-21 01:34:56119 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
120 "test.example.com", verify_result,
121 OK);
[email protected]50ca73e22013-09-30 00:37:50122 }
123
rchf114d982015-10-21 01:34:56124 // Creates a mock host resolver in which test.example.com
[email protected]50ca73e22013-09-30 00:37:50125 // resolves to localhost.
126 static MockHostResolver* CreateResolverImpl() {
127 MockHostResolver* resolver = new MockHostResolver();
rchf114d982015-10-21 01:34:56128 resolver->rules()->AddRule("test.example.com", "127.0.0.1");
[email protected]50ca73e22013-09-30 00:37:50129 return resolver;
130 }
131
dcheng67be2b1f2014-10-27 21:47:29132 void SetUp() override {
[email protected]50ca73e22013-09-30 00:37:50133 StartServer();
134
rchf114d982015-10-21 01:34:56135 // Use a mapped host resolver so that request for test.example.com (port 80)
[email protected]50ca73e22013-09-30 00:37:50136 // reach the server running on localhost.
Raul Tambre8c1981d2019-02-08 02:22:26137 std::string map_rule =
138 "MAP test.example.com test.example.com:" +
139 base::NumberToString(server_->server_address().port());
[email protected]50ca73e22013-09-30 00:37:50140 EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
141
142 // To simplify the test, and avoid the race with the HTTP request, we force
143 // QUIC for these requests.
Victor Vasilieva1e66d72019-12-05 17:55:38144 quic_context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:57145 HostPortPair::FromString("test.example.com:443"));
[email protected]50ca73e22013-09-30 00:37:50146
mmenke6ddfbea2017-05-31 21:48:41147 transaction_factory_.reset(
148 new TestTransactionFactory(session_params_, session_context_));
[email protected]50ca73e22013-09-30 00:37:50149 }
150
vasilvv479f0322016-11-29 16:06:48151 void TearDown() override {}
[email protected]50ca73e22013-09-30 00:37:50152
153 // Starts the QUIC server listening on a random port.
154 void StartServer() {
tfarinaa3dd7aa2016-02-25 08:15:44155 server_address_ = IPEndPoint(IPAddress(127, 0, 0, 1), 0);
[email protected]7d561352014-06-20 09:09:21156 server_config_.SetInitialStreamFlowControlWindowToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52157 quic::test::kInitialStreamFlowControlWindowForTest);
[email protected]7d561352014-06-20 09:09:21158 server_config_.SetInitialSessionFlowControlWindowToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52159 quic::test::kInitialSessionFlowControlWindowForTest);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52160 server_.reset(new QuicSimpleServer(
161 quic::test::crypto_test_utils::ProofSourceForTesting(), server_config_,
162 server_config_options_, quic::AllSupportedVersions(),
163 &memory_cache_backend_));
rche1d19cb2016-08-30 22:00:42164 server_->Listen(server_address_);
165 server_address_ = server_->server_address();
166 server_->StartReading();
[email protected]50ca73e22013-09-30 00:37:50167 server_started_ = true;
168 }
169
[email protected]50ca73e22013-09-30 00:37:50170 // Adds an entry to the cache used by the QUIC server to serve
171 // responses.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52172 void AddToCache(quic::QuicStringPiece path,
rchaa7859a12015-03-23 22:50:08173 int response_code,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52174 quic::QuicStringPiece response_detail,
175 quic::QuicStringPiece body) {
Rajesh Mahindrae6c0da12018-05-17 21:02:54176 memory_cache_backend_.AddSimpleResponse("test.example.com", path,
177 response_code, body);
[email protected]50ca73e22013-09-30 00:37:50178 }
179
180 // Populates |request_body_| with |length_| ASCII bytes.
181 void GenerateBody(size_t length) {
182 request_body_.clear();
183 request_body_.reserve(length);
184 for (size_t i = 0; i < length; ++i) {
185 request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
186 }
187 }
188
189 // Initializes |request_| for a post of |length| bytes.
190 void InitializePostRequest(size_t length) {
191 GenerateBody(length);
danakjad1777e2016-04-16 00:56:42192 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:19193 element_readers.push_back(std::make_unique<UploadBytesElementReader>(
ricea2deef682016-09-09 08:04:07194 request_body_.data(), request_body_.length()));
mmenkecbc2b712014-10-09 20:29:07195 upload_data_stream_.reset(
olli.raula6df48b2a2015-11-26 07:40:22196 new ElementsUploadDataStream(std::move(element_readers), 0));
[email protected]50ca73e22013-09-30 00:37:50197 request_.method = "POST";
rchf114d982015-10-21 01:34:56198 request_.url = GURL("https://test.example.com/");
[email protected]50ca73e22013-09-30 00:37:50199 request_.upload_data_stream = upload_data_stream_.get();
Bence Békyd8a21fc32018-06-27 18:29:58200 ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
tfarina428341112016-09-22 13:38:20201 NetLogWithSource()),
202 IsOk());
[email protected]50ca73e22013-09-30 00:37:50203 }
204
205 // Checks that |consumer| completed and received |status_line| and |body|.
206 void CheckResponse(const TestTransactionConsumer& consumer,
207 const std::string& status_line,
208 const std::string& body) {
209 ASSERT_TRUE(consumer.is_done());
robpercival214763f2016-07-01 23:27:01210 ASSERT_THAT(consumer.error(), IsOk());
rjshaded5ced072015-12-18 19:26:02211 EXPECT_EQ(status_line, consumer.response_info()->headers->GetStatusLine());
[email protected]50ca73e22013-09-30 00:37:50212 EXPECT_EQ(body, consumer.content());
213 }
214
Victor Vasiliev7752898d2019-11-14 21:30:22215 QuicContext quic_context_;
danakjad1777e2016-04-16 00:56:42216 std::unique_ptr<MockHostResolver> host_resolver_impl_;
[email protected]50ca73e22013-09-30 00:37:50217 MappedHostResolver host_resolver_;
218 MockCertVerifier cert_verifier_;
219 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42220 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23221 DefaultCTPolicyEnforcer ct_policy_enforcer_;
Ryan Sleevib8449e02018-07-15 04:31:07222 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59223 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42224 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:26225 HttpServerProperties http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41226 HttpNetworkSession::Params session_params_;
227 HttpNetworkSession::Context session_context_;
danakjad1777e2016-04-16 00:56:42228 std::unique_ptr<TestTransactionFactory> transaction_factory_;
[email protected]50ca73e22013-09-30 00:37:50229 HttpRequestInfo request_;
230 std::string request_body_;
danakjad1777e2016-04-16 00:56:42231 std::unique_ptr<UploadDataStream> upload_data_stream_;
rche1d19cb2016-08-30 22:00:42232 std::unique_ptr<QuicSimpleServer> server_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52233 quic::QuicMemoryCacheBackend memory_cache_backend_;
[email protected]50ca73e22013-09-30 00:37:50234 IPEndPoint server_address_;
235 std::string server_hostname_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52236 quic::QuicConfig server_config_;
237 quic::QuicCryptoServerConfig::ConfigOptions server_config_options_;
[email protected]50ca73e22013-09-30 00:37:50238 bool server_started_;
239 bool strike_register_no_startup_period_;
240};
241
Ryan Hamilton367b7312019-05-30 01:21:33242TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
[email protected]50ca73e22013-09-30 00:37:50243 std::string response(10 * 1024, 'x');
244
rchaa7859a12015-03-23 22:50:08245 AddToCache(request_.url.PathForRequest(), 200, "OK", response);
[email protected]50ca73e22013-09-30 00:37:50246
247 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
248 transaction_factory_.get());
tfarina428341112016-09-22 13:38:20249 consumer.Start(&request_, NetLogWithSource());
[email protected]50ca73e22013-09-30 00:37:50250
251 // Will terminate when the last consumer completes.
fdoraye1e050c52016-07-19 21:05:54252 base::RunLoop().Run();
[email protected]50ca73e22013-09-30 00:37:50253
bnc84e7fb52015-12-02 11:50:02254 CheckResponse(consumer, "HTTP/1.1 200", response);
[email protected]50ca73e22013-09-30 00:37:50255}
256
rtennetie3b666d2016-01-08 05:07:28257// crbug.com/559173
258#if defined(THREAD_SANITIZER)
Ryan Hamilton367b7312019-05-30 01:21:33259TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28260#else
Ryan Hamilton367b7312019-05-30 01:21:33261TEST_F(QuicEndToEndTest, LargePostWithNoPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28262#endif
rtenneti97238d662015-10-23 16:16:58263 InitializePostRequest(1024 * 1024);
[email protected]50ca73e22013-09-30 00:37:50264
rchaa7859a12015-03-23 22:50:08265 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50266
267 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
268 transaction_factory_.get());
tfarina428341112016-09-22 13:38:20269 consumer.Start(&request_, NetLogWithSource());
[email protected]50ca73e22013-09-30 00:37:50270
271 // Will terminate when the last consumer completes.
fdoraye1e050c52016-07-19 21:05:54272 base::RunLoop().Run();
[email protected]50ca73e22013-09-30 00:37:50273
bnc84e7fb52015-12-02 11:50:02274 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50275}
276
rtennetie3b666d2016-01-08 05:07:28277// crbug.com/559173
278#if defined(THREAD_SANITIZER)
Ryan Hamilton367b7312019-05-30 01:21:33279TEST_F(QuicEndToEndTest, DISABLED_LargePostWithPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28280#else
Ryan Hamilton367b7312019-05-30 01:21:33281TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28282#endif
[email protected]50ca73e22013-09-30 00:37:50283 // FLAGS_fake_packet_loss_percentage = 30;
284 InitializePostRequest(1024 * 1024);
285
286 const char kResponseBody[] = "some really big response body";
rchaa7859a12015-03-23 22:50:08287 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50288
289 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
290 transaction_factory_.get());
tfarina428341112016-09-22 13:38:20291 consumer.Start(&request_, NetLogWithSource());
[email protected]50ca73e22013-09-30 00:37:50292
293 // Will terminate when the last consumer completes.
fdoraye1e050c52016-07-19 21:05:54294 base::RunLoop().Run();
[email protected]50ca73e22013-09-30 00:37:50295
bnc84e7fb52015-12-02 11:50:02296 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50297}
298
zhaoqinf60fa492015-09-30 16:24:08299// crbug.com/536845
300#if defined(THREAD_SANITIZER)
Ryan Hamilton367b7312019-05-30 01:21:33301TEST_F(QuicEndToEndTest, DISABLED_UberTest) {
zhaoqinf60fa492015-09-30 16:24:08302#else
Ryan Hamilton367b7312019-05-30 01:21:33303TEST_F(QuicEndToEndTest, UberTest) {
zhaoqinf60fa492015-09-30 16:24:08304#endif
[email protected]50ca73e22013-09-30 00:37:50305 // FLAGS_fake_packet_loss_percentage = 30;
306
307 const char kResponseBody[] = "some really big response body";
rchaa7859a12015-03-23 22:50:08308 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50309
avib3635452016-10-21 18:33:53310 std::vector<std::unique_ptr<TestTransactionConsumer>> consumers;
311 for (size_t i = 0; i < 100; ++i) {
rjshaded5ced072015-12-18 19:26:02312 TestTransactionConsumer* consumer = new TestTransactionConsumer(
313 DEFAULT_PRIORITY, transaction_factory_.get());
avib3635452016-10-21 18:33:53314 consumers.push_back(base::WrapUnique(consumer));
tfarina428341112016-09-22 13:38:20315 consumer->Start(&request_, NetLogWithSource());
[email protected]50ca73e22013-09-30 00:37:50316 }
317
318 // Will terminate when the last consumer completes.
fdoraye1e050c52016-07-19 21:05:54319 base::RunLoop().Run();
[email protected]50ca73e22013-09-30 00:37:50320
avib3635452016-10-21 18:33:53321 for (const auto& consumer : consumers)
322 CheckResponse(*consumer.get(), "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50323}
324
325} // namespace test
326} // namespace net