blob: 87ca6fe040a269a2b06cbc7e6b90d2d7457afc37 [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"
[email protected]50ca73e22013-09-30 00:37:5012#include "base/stl_util.h"
13#include "base/strings/string_number_conversions.h"
mmenkecbc2b712014-10-09 20:29:0714#include "net/base/elements_upload_data_stream.h"
martijncc5402d2016-02-16 19:08:5815#include "net/base/ip_address.h"
[email protected]50ca73e22013-09-30 00:37:5016#include "net/base/test_completion_callback.h"
rchf114d982015-10-21 01:34:5617#include "net/base/test_data_directory.h"
[email protected]50ca73e22013-09-30 00:37:5018#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"
28#include "net/http/http_server_properties_impl.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"
31#include "net/proxy/proxy_service.h"
rchf114d982015-10-21 01:34:5632#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]9bb57c72014-03-31 20:36:0433#include "net/quic/test_tools/quic_test_utils.h"
nharperd5cddca2016-02-27 03:37:5234#include "net/ssl/default_channel_id_store.h"
[email protected]50ca73e22013-09-30 00:37:5035#include "net/ssl/ssl_config_service_defaults.h"
rchf114d982015-10-21 01:34:5636#include "net/test/cert_test_util.h"
[email protected]50ca73e22013-09-30 00:37:5037#include "net/tools/quic/quic_in_memory_cache.h"
[email protected]a5b98172014-06-18 07:01:5938#include "net/tools/quic/quic_server.h"
[email protected]50ca73e22013-09-30 00:37:5039#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
40#include "net/tools/quic/test_tools/server_thread.h"
41#include "testing/gtest/include/gtest/gtest.h"
42#include "testing/platform_test.h"
43
[email protected]50ca73e22013-09-30 00:37:5044using base::StringPiece;
[email protected]50ca73e22013-09-30 00:37:5045
46namespace net {
ttuttle859dc7a2015-04-23 19:42:2947
rch750447f92016-01-31 02:54:5348using test::QuicInMemoryCachePeer;
49using test::ServerThread;
ttuttle859dc7a2015-04-23 19:42:2950
[email protected]50ca73e22013-09-30 00:37:5051namespace test {
52
53namespace {
54
55const char kResponseBody[] = "some arbitrary response body";
56
57// Factory for creating HttpTransactions, used by TestTransactionConsumer.
58class TestTransactionFactory : public HttpTransactionFactory {
59 public:
mmenkee65e7af2015-10-13 17:16:4260 explicit TestTransactionFactory(const HttpNetworkSession::Params& params)
[email protected]50ca73e22013-09-30 00:37:5061 : session_(new HttpNetworkSession(params)) {}
62
dcheng67be2b1f2014-10-27 21:47:2963 ~TestTransactionFactory() override {}
[email protected]50ca73e22013-09-30 00:37:5064
65 // HttpTransactionFactory methods
dcheng67be2b1f2014-10-27 21:47:2966 int CreateTransaction(RequestPriority priority,
danakjad1777e2016-04-16 00:56:4267 std::unique_ptr<HttpTransaction>* trans) override {
dcheng4227c6d2014-08-25 23:58:1868 trans->reset(new HttpNetworkTransaction(priority, session_.get()));
[email protected]50ca73e22013-09-30 00:37:5069 return OK;
70 }
71
dcheng67be2b1f2014-10-27 21:47:2972 HttpCache* GetCache() override { return nullptr; }
[email protected]50ca73e22013-09-30 00:37:5073
dcheng67be2b1f2014-10-27 21:47:2974 HttpNetworkSession* GetSession() override { return session_.get(); };
[email protected]50ca73e22013-09-30 00:37:5075
76 private:
danakjad1777e2016-04-16 00:56:4277 std::unique_ptr<HttpNetworkSession> session_;
[email protected]50ca73e22013-09-30 00:37:5078};
79
rchf37ccc782016-01-31 05:13:5080struct TestParams {
81 explicit TestParams(bool use_stateless_rejects)
82 : use_stateless_rejects(use_stateless_rejects) {}
83
84 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
85 os << "{ use_stateless_rejects: " << p.use_stateless_rejects << " }";
86 return os;
87 }
88 bool use_stateless_rejects;
89};
90
91std::vector<TestParams> GetTestParams() {
92 return std::vector<TestParams>{TestParams(true), TestParams(false)};
93}
94
[email protected]50ca73e22013-09-30 00:37:5095} // namespace
96
rchf37ccc782016-01-31 05:13:5097class QuicEndToEndTest : public ::testing::TestWithParam<TestParams> {
[email protected]50ca73e22013-09-30 00:37:5098 protected:
99 QuicEndToEndTest()
100 : host_resolver_impl_(CreateResolverImpl()),
dchengc7eeda422015-12-26 03:56:48101 host_resolver_(std::move(host_resolver_impl_)),
rtenneti052774e2015-11-24 21:00:12102 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]50ca73e22013-09-30 00:37:50103 ssl_config_service_(new SSLConfigServiceDefaults),
104 proxy_service_(ProxyService::CreateDirect()),
105 auth_handler_factory_(
[email protected]d4adc302013-09-30 03:02:34106 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
107 strike_register_no_startup_period_(false) {
[email protected]50ca73e22013-09-30 00:37:50108 request_.method = "GET";
rchf114d982015-10-21 01:34:56109 request_.url = GURL("https://test.example.com/");
[email protected]50ca73e22013-09-30 00:37:50110 request_.load_flags = 0;
111
112 params_.enable_quic = true;
rtennetibe635732014-10-02 22:51:42113 params_.quic_clock = nullptr;
114 params_.quic_random = nullptr;
rchf37ccc782016-01-31 05:13:50115 if (GetParam().use_stateless_rejects) {
116 params_.quic_connection_options.push_back(kSREJ);
117 }
[email protected]50ca73e22013-09-30 00:37:50118 params_.host_resolver = &host_resolver_;
119 params_.cert_verifier = &cert_verifier_;
120 params_.transport_security_state = &transport_security_state_;
rtenneti052774e2015-11-24 21:00:12121 params_.cert_transparency_verifier = cert_transparency_verifier_.get();
rsleevid6de8302016-06-21 01:33:20122 params_.ct_policy_enforcer = &ct_policy_enforcer_;
[email protected]50ca73e22013-09-30 00:37:50123 params_.proxy_service = proxy_service_.get();
124 params_.ssl_config_service = ssl_config_service_.get();
125 params_.http_auth_handler_factory = auth_handler_factory_.get();
bnc525e175a2016-06-20 12:36:40126 params_.http_server_properties = &http_server_properties_;
nharperd5cddca2016-02-27 03:37:52127 channel_id_service_.reset(
128 new ChannelIDService(new DefaultChannelIDStore(nullptr),
129 base::ThreadTaskRunnerHandle::Get()));
130 params_.channel_id_service = channel_id_service_.get();
rchf114d982015-10-21 01:34:56131
tfarinaa3dd7aa2016-02-25 08:15:44132 CertVerifyResult verify_result;
rchf114d982015-10-21 01:34:56133 verify_result.verified_cert = ImportCertFromFile(
134 GetTestCertsDirectory(), "quic_test.example.com.crt");
135 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
136 "test.example.com", verify_result,
137 OK);
138 verify_result.verified_cert = ImportCertFromFile(
139 GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
140 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
141 "test.example.com", verify_result,
142 OK);
[email protected]50ca73e22013-09-30 00:37:50143 }
144
rchf114d982015-10-21 01:34:56145 // Creates a mock host resolver in which test.example.com
[email protected]50ca73e22013-09-30 00:37:50146 // resolves to localhost.
147 static MockHostResolver* CreateResolverImpl() {
148 MockHostResolver* resolver = new MockHostResolver();
rchf114d982015-10-21 01:34:56149 resolver->rules()->AddRule("test.example.com", "127.0.0.1");
[email protected]50ca73e22013-09-30 00:37:50150 return resolver;
151 }
152
dcheng67be2b1f2014-10-27 21:47:29153 void SetUp() override {
[email protected]50ca73e22013-09-30 00:37:50154 QuicInMemoryCachePeer::ResetForTests();
155 StartServer();
156
rchf114d982015-10-21 01:34:56157 // Use a mapped host resolver so that request for test.example.com (port 80)
[email protected]50ca73e22013-09-30 00:37:50158 // reach the server running on localhost.
rchf114d982015-10-21 01:34:56159 std::string map_rule = "MAP test.example.com test.example.com:" +
160 base::IntToString(server_thread_->GetPort());
[email protected]50ca73e22013-09-30 00:37:50161 EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
162
163 // To simplify the test, and avoid the race with the HTTP request, we force
164 // QUIC for these requests.
rtenneti8a2f4632016-03-21 20:26:57165 params_.origins_to_force_quic_on.insert(
166 HostPortPair::FromString("test.example.com:443"));
[email protected]50ca73e22013-09-30 00:37:50167
168 transaction_factory_.reset(new TestTransactionFactory(params_));
169 }
170
dcheng67be2b1f2014-10-27 21:47:29171 void TearDown() override {
[email protected]50ca73e22013-09-30 00:37:50172 StopServer();
173 QuicInMemoryCachePeer::ResetForTests();
174 }
175
176 // Starts the QUIC server listening on a random port.
177 void StartServer() {
tfarinaa3dd7aa2016-02-25 08:15:44178 server_address_ = IPEndPoint(IPAddress(127, 0, 0, 1), 0);
[email protected]7d561352014-06-20 09:09:21179 server_config_.SetInitialStreamFlowControlWindowToSend(
180 kInitialStreamFlowControlWindowForTest);
181 server_config_.SetInitialSessionFlowControlWindowToSend(
182 kInitialSessionFlowControlWindowForTest);
nharperd5cddca2016-02-27 03:37:52183 server_config_options_.token_binding_enabled = true;
rchf114d982015-10-21 01:34:56184 QuicServer* server =
rch1fe2eeb2015-10-26 14:45:57185 new QuicServer(CryptoTestUtils::ProofSourceForTesting(), server_config_,
nharperd5cddca2016-02-27 03:37:52186 server_config_options_, QuicSupportedVersions());
rch1fe2eeb2015-10-26 14:45:57187 server_thread_.reset(new ServerThread(server, server_address_,
rchf114d982015-10-21 01:34:56188 strike_register_no_startup_period_));
[email protected]8c2cfd62014-01-09 19:13:03189 server_thread_->Initialize();
rjshaded5ced072015-12-18 19:26:02190 server_address_ =
191 IPEndPoint(server_address_.address(), server_thread_->GetPort());
[email protected]8c2cfd62014-01-09 19:13:03192 server_thread_->Start();
[email protected]50ca73e22013-09-30 00:37:50193 server_started_ = true;
194 }
195
196 // Stops the QUIC server.
197 void StopServer() {
198 if (!server_started_) {
199 return;
200 }
201 if (server_thread_.get()) {
[email protected]98f49e42013-11-08 19:30:57202 server_thread_->Quit();
[email protected]50ca73e22013-09-30 00:37:50203 server_thread_->Join();
204 }
205 }
206
207 // Adds an entry to the cache used by the QUIC server to serve
208 // responses.
rchaa7859a12015-03-23 22:50:08209 void AddToCache(StringPiece path,
210 int response_code,
211 StringPiece response_detail,
212 StringPiece body) {
[email protected]50ca73e22013-09-30 00:37:50213 QuicInMemoryCache::GetInstance()->AddSimpleResponse(
rtennetic82ee4e32015-11-11 04:32:34214 "test.example.com", path, response_code, body);
[email protected]50ca73e22013-09-30 00:37:50215 }
216
217 // Populates |request_body_| with |length_| ASCII bytes.
218 void GenerateBody(size_t length) {
219 request_body_.clear();
220 request_body_.reserve(length);
221 for (size_t i = 0; i < length; ++i) {
222 request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
223 }
224 }
225
226 // Initializes |request_| for a post of |length| bytes.
227 void InitializePostRequest(size_t length) {
228 GenerateBody(length);
danakjad1777e2016-04-16 00:56:42229 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
230 element_readers.push_back(base::WrapUnique(new UploadBytesElementReader(
olli.raula6df48b2a2015-11-26 07:40:22231 request_body_.data(), request_body_.length())));
mmenkecbc2b712014-10-09 20:29:07232 upload_data_stream_.reset(
olli.raula6df48b2a2015-11-26 07:40:22233 new ElementsUploadDataStream(std::move(element_readers), 0));
[email protected]50ca73e22013-09-30 00:37:50234 request_.method = "POST";
rchf114d982015-10-21 01:34:56235 request_.url = GURL("https://test.example.com/");
[email protected]50ca73e22013-09-30 00:37:50236 request_.upload_data_stream = upload_data_stream_.get();
237 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
238 }
239
240 // Checks that |consumer| completed and received |status_line| and |body|.
241 void CheckResponse(const TestTransactionConsumer& consumer,
242 const std::string& status_line,
243 const std::string& body) {
244 ASSERT_TRUE(consumer.is_done());
rchf114d982015-10-21 01:34:56245 ASSERT_EQ(OK, consumer.error());
rjshaded5ced072015-12-18 19:26:02246 EXPECT_EQ(status_line, consumer.response_info()->headers->GetStatusLine());
[email protected]50ca73e22013-09-30 00:37:50247 EXPECT_EQ(body, consumer.content());
248 }
249
danakjad1777e2016-04-16 00:56:42250 std::unique_ptr<MockHostResolver> host_resolver_impl_;
[email protected]50ca73e22013-09-30 00:37:50251 MappedHostResolver host_resolver_;
252 MockCertVerifier cert_verifier_;
danakjad1777e2016-04-16 00:56:42253 std::unique_ptr<ChannelIDService> channel_id_service_;
[email protected]50ca73e22013-09-30 00:37:50254 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42255 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
rsleevid6de8302016-06-21 01:33:20256 CTPolicyEnforcer ct_policy_enforcer_;
[email protected]50ca73e22013-09-30 00:37:50257 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
danakjad1777e2016-04-16 00:56:42258 std::unique_ptr<ProxyService> proxy_service_;
259 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc525e175a2016-06-20 12:36:40260 HttpServerPropertiesImpl http_server_properties_;
[email protected]50ca73e22013-09-30 00:37:50261 HttpNetworkSession::Params params_;
danakjad1777e2016-04-16 00:56:42262 std::unique_ptr<TestTransactionFactory> transaction_factory_;
[email protected]50ca73e22013-09-30 00:37:50263 HttpRequestInfo request_;
264 std::string request_body_;
danakjad1777e2016-04-16 00:56:42265 std::unique_ptr<UploadDataStream> upload_data_stream_;
266 std::unique_ptr<ServerThread> server_thread_;
[email protected]50ca73e22013-09-30 00:37:50267 IPEndPoint server_address_;
268 std::string server_hostname_;
269 QuicConfig server_config_;
nharperd5cddca2016-02-27 03:37:52270 QuicCryptoServerConfig::ConfigOptions server_config_options_;
[email protected]50ca73e22013-09-30 00:37:50271 bool server_started_;
272 bool strike_register_no_startup_period_;
273};
274
rchf37ccc782016-01-31 05:13:50275INSTANTIATE_TEST_CASE_P(Tests,
276 QuicEndToEndTest,
277 ::testing::ValuesIn(GetTestParams()));
278
279TEST_P(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
[email protected]50ca73e22013-09-30 00:37:50280 std::string response(10 * 1024, 'x');
281
rchaa7859a12015-03-23 22:50:08282 AddToCache(request_.url.PathForRequest(), 200, "OK", response);
[email protected]50ca73e22013-09-30 00:37:50283
284 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
285 transaction_factory_.get());
286 consumer.Start(&request_, BoundNetLog());
287
288 // Will terminate when the last consumer completes.
289 base::MessageLoop::current()->Run();
290
bnc84e7fb52015-12-02 11:50:02291 CheckResponse(consumer, "HTTP/1.1 200", response);
[email protected]50ca73e22013-09-30 00:37:50292}
293
nharperd5cddca2016-02-27 03:37:52294TEST_P(QuicEndToEndTest, TokenBinding) {
295 // Enable token binding and re-initialize the TestTransactionFactory.
296 params_.enable_token_binding = true;
297 transaction_factory_.reset(new TestTransactionFactory(params_));
298
299 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
300
301 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
302 transaction_factory_.get());
303 consumer.Start(&request_, BoundNetLog());
304
305 // Will terminate when the last consumer completes.
306 base::MessageLoop::current()->Run();
307
308 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
309 HttpRequestHeaders headers;
310 ASSERT_TRUE(consumer.transaction()->GetFullRequestHeaders(&headers));
311 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
312}
313
rtennetie3b666d2016-01-08 05:07:28314// crbug.com/559173
315#if defined(THREAD_SANITIZER)
rchf37ccc782016-01-31 05:13:50316TEST_P(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28317#else
rchf37ccc782016-01-31 05:13:50318TEST_P(QuicEndToEndTest, LargePostWithNoPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28319#endif
rtenneti97238d662015-10-23 16:16:58320 InitializePostRequest(1024 * 1024);
[email protected]50ca73e22013-09-30 00:37:50321
rchaa7859a12015-03-23 22:50:08322 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50323
324 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
325 transaction_factory_.get());
326 consumer.Start(&request_, BoundNetLog());
327
328 // Will terminate when the last consumer completes.
329 base::MessageLoop::current()->Run();
330
bnc84e7fb52015-12-02 11:50:02331 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50332}
333
rtennetie3b666d2016-01-08 05:07:28334// crbug.com/559173
335#if defined(THREAD_SANITIZER)
rchf37ccc782016-01-31 05:13:50336TEST_P(QuicEndToEndTest, DISABLED_LargePostWithPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28337#else
rchf37ccc782016-01-31 05:13:50338TEST_P(QuicEndToEndTest, LargePostWithPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28339#endif
[email protected]50ca73e22013-09-30 00:37:50340 // FLAGS_fake_packet_loss_percentage = 30;
341 InitializePostRequest(1024 * 1024);
342
343 const char kResponseBody[] = "some really big response body";
rchaa7859a12015-03-23 22:50:08344 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50345
346 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
347 transaction_factory_.get());
348 consumer.Start(&request_, BoundNetLog());
349
350 // Will terminate when the last consumer completes.
351 base::MessageLoop::current()->Run();
352
bnc84e7fb52015-12-02 11:50:02353 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50354}
355
zhaoqinf60fa492015-09-30 16:24:08356// crbug.com/536845
357#if defined(THREAD_SANITIZER)
rchf37ccc782016-01-31 05:13:50358TEST_P(QuicEndToEndTest, DISABLED_UberTest) {
zhaoqinf60fa492015-09-30 16:24:08359#else
rchf37ccc782016-01-31 05:13:50360TEST_P(QuicEndToEndTest, UberTest) {
zhaoqinf60fa492015-09-30 16:24:08361#endif
[email protected]50ca73e22013-09-30 00:37:50362 // FLAGS_fake_packet_loss_percentage = 30;
363
364 const char kResponseBody[] = "some really big response body";
rchaa7859a12015-03-23 22:50:08365 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50366
367 std::vector<TestTransactionConsumer*> consumers;
368 size_t num_requests = 100;
369 for (size_t i = 0; i < num_requests; ++i) {
rjshaded5ced072015-12-18 19:26:02370 TestTransactionConsumer* consumer = new TestTransactionConsumer(
371 DEFAULT_PRIORITY, transaction_factory_.get());
372 consumers.push_back(consumer);
373 consumer->Start(&request_, BoundNetLog());
[email protected]50ca73e22013-09-30 00:37:50374 }
375
376 // Will terminate when the last consumer completes.
377 base::MessageLoop::current()->Run();
378
379 for (size_t i = 0; i < num_requests; ++i) {
bnc84e7fb52015-12-02 11:50:02380 CheckResponse(*consumers[i], "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50381 }
382 STLDeleteElements(&consumers);
383}
384
385} // namespace test
386} // namespace net