blob: 7441c7f36f19350ab0d699895c0f4d7985cae339 [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
rchf37ccc782016-01-31 05:13:505#include <ostream>
dchengc7eeda422015-12-26 03:56:486#include <utility>
olli.raula6df48b2a2015-11-26 07:40:227#include <vector>
8
[email protected]50ca73e22013-09-30 00:37:509#include "base/compiler_specific.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/stl_util.h"
12#include "base/strings/string_number_conversions.h"
mmenkecbc2b712014-10-09 20:29:0713#include "net/base/elements_upload_data_stream.h"
martijncc5402d2016-02-16 19:08:5814#include "net/base/ip_address.h"
[email protected]50ca73e22013-09-30 00:37:5015#include "net/base/test_completion_callback.h"
rchf114d982015-10-21 01:34:5616#include "net/base/test_data_directory.h"
[email protected]50ca73e22013-09-30 00:37:5017#include "net/base/upload_bytes_element_reader.h"
18#include "net/base/upload_data_stream.h"
19#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1220#include "net/cert/multi_log_ct_verifier.h"
[email protected]50ca73e22013-09-30 00:37:5021#include "net/dns/mapped_host_resolver.h"
22#include "net/dns/mock_host_resolver.h"
23#include "net/http/http_auth_handler_factory.h"
24#include "net/http/http_network_session.h"
25#include "net/http/http_network_transaction.h"
26#include "net/http/http_server_properties_impl.h"
[email protected]c41737d2014-05-14 07:47:1927#include "net/http/http_transaction_test_util.h"
[email protected]50ca73e22013-09-30 00:37:5028#include "net/http/transport_security_state.h"
29#include "net/proxy/proxy_service.h"
rchf114d982015-10-21 01:34:5630#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]9bb57c72014-03-31 20:36:0431#include "net/quic/test_tools/quic_test_utils.h"
nharperd5cddca2016-02-27 03:37:5232#include "net/ssl/default_channel_id_store.h"
[email protected]50ca73e22013-09-30 00:37:5033#include "net/ssl/ssl_config_service_defaults.h"
rchf114d982015-10-21 01:34:5634#include "net/test/cert_test_util.h"
[email protected]50ca73e22013-09-30 00:37:5035#include "net/tools/quic/quic_in_memory_cache.h"
[email protected]a5b98172014-06-18 07:01:5936#include "net/tools/quic/quic_server.h"
[email protected]50ca73e22013-09-30 00:37:5037#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
38#include "net/tools/quic/test_tools/server_thread.h"
39#include "testing/gtest/include/gtest/gtest.h"
40#include "testing/platform_test.h"
41
[email protected]50ca73e22013-09-30 00:37:5042using base::StringPiece;
[email protected]50ca73e22013-09-30 00:37:5043
44namespace net {
ttuttle859dc7a2015-04-23 19:42:2945
rch750447f92016-01-31 02:54:5346using test::QuicInMemoryCachePeer;
47using test::ServerThread;
ttuttle859dc7a2015-04-23 19:42:2948
[email protected]50ca73e22013-09-30 00:37:5049namespace test {
50
51namespace {
52
53const char kResponseBody[] = "some arbitrary response body";
54
55// Factory for creating HttpTransactions, used by TestTransactionConsumer.
56class TestTransactionFactory : public HttpTransactionFactory {
57 public:
mmenkee65e7af2015-10-13 17:16:4258 explicit TestTransactionFactory(const HttpNetworkSession::Params& params)
[email protected]50ca73e22013-09-30 00:37:5059 : session_(new HttpNetworkSession(params)) {}
60
dcheng67be2b1f2014-10-27 21:47:2961 ~TestTransactionFactory() override {}
[email protected]50ca73e22013-09-30 00:37:5062
63 // HttpTransactionFactory methods
dcheng67be2b1f2014-10-27 21:47:2964 int CreateTransaction(RequestPriority priority,
65 scoped_ptr<HttpTransaction>* trans) override {
dcheng4227c6d2014-08-25 23:58:1866 trans->reset(new HttpNetworkTransaction(priority, session_.get()));
[email protected]50ca73e22013-09-30 00:37:5067 return OK;
68 }
69
dcheng67be2b1f2014-10-27 21:47:2970 HttpCache* GetCache() override { return nullptr; }
[email protected]50ca73e22013-09-30 00:37:5071
dcheng67be2b1f2014-10-27 21:47:2972 HttpNetworkSession* GetSession() override { return session_.get(); };
[email protected]50ca73e22013-09-30 00:37:5073
74 private:
mmenkee65e7af2015-10-13 17:16:4275 scoped_ptr<HttpNetworkSession> session_;
[email protected]50ca73e22013-09-30 00:37:5076};
77
rchf37ccc782016-01-31 05:13:5078struct TestParams {
79 explicit TestParams(bool use_stateless_rejects)
80 : use_stateless_rejects(use_stateless_rejects) {}
81
82 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
83 os << "{ use_stateless_rejects: " << p.use_stateless_rejects << " }";
84 return os;
85 }
86 bool use_stateless_rejects;
87};
88
89std::vector<TestParams> GetTestParams() {
90 return std::vector<TestParams>{TestParams(true), TestParams(false)};
91}
92
[email protected]50ca73e22013-09-30 00:37:5093} // namespace
94
rchf37ccc782016-01-31 05:13:5095class QuicEndToEndTest : public ::testing::TestWithParam<TestParams> {
[email protected]50ca73e22013-09-30 00:37:5096 protected:
97 QuicEndToEndTest()
98 : host_resolver_impl_(CreateResolverImpl()),
dchengc7eeda422015-12-26 03:56:4899 host_resolver_(std::move(host_resolver_impl_)),
rtenneti052774e2015-11-24 21:00:12100 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]50ca73e22013-09-30 00:37:50101 ssl_config_service_(new SSLConfigServiceDefaults),
102 proxy_service_(ProxyService::CreateDirect()),
103 auth_handler_factory_(
[email protected]d4adc302013-09-30 03:02:34104 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
105 strike_register_no_startup_period_(false) {
[email protected]50ca73e22013-09-30 00:37:50106 request_.method = "GET";
rchf114d982015-10-21 01:34:56107 request_.url = GURL("https://test.example.com/");
[email protected]50ca73e22013-09-30 00:37:50108 request_.load_flags = 0;
109
110 params_.enable_quic = true;
rtennetibe635732014-10-02 22:51:42111 params_.quic_clock = nullptr;
112 params_.quic_random = nullptr;
rchf37ccc782016-01-31 05:13:50113 if (GetParam().use_stateless_rejects) {
114 params_.quic_connection_options.push_back(kSREJ);
115 }
[email protected]50ca73e22013-09-30 00:37:50116 params_.host_resolver = &host_resolver_;
117 params_.cert_verifier = &cert_verifier_;
118 params_.transport_security_state = &transport_security_state_;
rtenneti052774e2015-11-24 21:00:12119 params_.cert_transparency_verifier = cert_transparency_verifier_.get();
[email protected]50ca73e22013-09-30 00:37:50120 params_.proxy_service = proxy_service_.get();
121 params_.ssl_config_service = ssl_config_service_.get();
122 params_.http_auth_handler_factory = auth_handler_factory_.get();
123 params_.http_server_properties = http_server_properties.GetWeakPtr();
nharperd5cddca2016-02-27 03:37:52124 channel_id_service_.reset(
125 new ChannelIDService(new DefaultChannelIDStore(nullptr),
126 base::ThreadTaskRunnerHandle::Get()));
127 params_.channel_id_service = channel_id_service_.get();
rchf114d982015-10-21 01:34:56128
tfarinaa3dd7aa2016-02-25 08:15:44129 CertVerifyResult verify_result;
rchf114d982015-10-21 01:34:56130 verify_result.verified_cert = ImportCertFromFile(
131 GetTestCertsDirectory(), "quic_test.example.com.crt");
132 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
133 "test.example.com", verify_result,
134 OK);
135 verify_result.verified_cert = ImportCertFromFile(
136 GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
137 cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
138 "test.example.com", verify_result,
139 OK);
[email protected]50ca73e22013-09-30 00:37:50140 }
141
rchf114d982015-10-21 01:34:56142 // Creates a mock host resolver in which test.example.com
[email protected]50ca73e22013-09-30 00:37:50143 // resolves to localhost.
144 static MockHostResolver* CreateResolverImpl() {
145 MockHostResolver* resolver = new MockHostResolver();
rchf114d982015-10-21 01:34:56146 resolver->rules()->AddRule("test.example.com", "127.0.0.1");
[email protected]50ca73e22013-09-30 00:37:50147 return resolver;
148 }
149
dcheng67be2b1f2014-10-27 21:47:29150 void SetUp() override {
[email protected]50ca73e22013-09-30 00:37:50151 QuicInMemoryCachePeer::ResetForTests();
152 StartServer();
153
rchf114d982015-10-21 01:34:56154 // Use a mapped host resolver so that request for test.example.com (port 80)
[email protected]50ca73e22013-09-30 00:37:50155 // reach the server running on localhost.
rchf114d982015-10-21 01:34:56156 std::string map_rule = "MAP test.example.com test.example.com:" +
157 base::IntToString(server_thread_->GetPort());
[email protected]50ca73e22013-09-30 00:37:50158 EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
159
160 // To simplify the test, and avoid the race with the HTTP request, we force
161 // QUIC for these requests.
rtenneti8a2f4632016-03-21 20:26:57162 params_.origins_to_force_quic_on.insert(
163 HostPortPair::FromString("test.example.com:443"));
[email protected]50ca73e22013-09-30 00:37:50164
165 transaction_factory_.reset(new TestTransactionFactory(params_));
166 }
167
dcheng67be2b1f2014-10-27 21:47:29168 void TearDown() override {
[email protected]50ca73e22013-09-30 00:37:50169 StopServer();
170 QuicInMemoryCachePeer::ResetForTests();
171 }
172
173 // Starts the QUIC server listening on a random port.
174 void StartServer() {
tfarinaa3dd7aa2016-02-25 08:15:44175 server_address_ = IPEndPoint(IPAddress(127, 0, 0, 1), 0);
[email protected]7d561352014-06-20 09:09:21176 server_config_.SetInitialStreamFlowControlWindowToSend(
177 kInitialStreamFlowControlWindowForTest);
178 server_config_.SetInitialSessionFlowControlWindowToSend(
179 kInitialSessionFlowControlWindowForTest);
nharperd5cddca2016-02-27 03:37:52180 server_config_options_.token_binding_enabled = true;
rchf114d982015-10-21 01:34:56181 QuicServer* server =
rch1fe2eeb2015-10-26 14:45:57182 new QuicServer(CryptoTestUtils::ProofSourceForTesting(), server_config_,
nharperd5cddca2016-02-27 03:37:52183 server_config_options_, QuicSupportedVersions());
rch1fe2eeb2015-10-26 14:45:57184 server_thread_.reset(new ServerThread(server, server_address_,
rchf114d982015-10-21 01:34:56185 strike_register_no_startup_period_));
[email protected]8c2cfd62014-01-09 19:13:03186 server_thread_->Initialize();
rjshaded5ced072015-12-18 19:26:02187 server_address_ =
188 IPEndPoint(server_address_.address(), server_thread_->GetPort());
[email protected]8c2cfd62014-01-09 19:13:03189 server_thread_->Start();
[email protected]50ca73e22013-09-30 00:37:50190 server_started_ = true;
191 }
192
193 // Stops the QUIC server.
194 void StopServer() {
195 if (!server_started_) {
196 return;
197 }
198 if (server_thread_.get()) {
[email protected]98f49e42013-11-08 19:30:57199 server_thread_->Quit();
[email protected]50ca73e22013-09-30 00:37:50200 server_thread_->Join();
201 }
202 }
203
204 // Adds an entry to the cache used by the QUIC server to serve
205 // responses.
rchaa7859a12015-03-23 22:50:08206 void AddToCache(StringPiece path,
207 int response_code,
208 StringPiece response_detail,
209 StringPiece body) {
[email protected]50ca73e22013-09-30 00:37:50210 QuicInMemoryCache::GetInstance()->AddSimpleResponse(
rtennetic82ee4e32015-11-11 04:32:34211 "test.example.com", path, response_code, body);
[email protected]50ca73e22013-09-30 00:37:50212 }
213
214 // Populates |request_body_| with |length_| ASCII bytes.
215 void GenerateBody(size_t length) {
216 request_body_.clear();
217 request_body_.reserve(length);
218 for (size_t i = 0; i < length; ++i) {
219 request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
220 }
221 }
222
223 // Initializes |request_| for a post of |length| bytes.
224 void InitializePostRequest(size_t length) {
225 GenerateBody(length);
olli.raula6df48b2a2015-11-26 07:40:22226 std::vector<scoped_ptr<UploadElementReader>> element_readers;
227 element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader(
228 request_body_.data(), request_body_.length())));
mmenkecbc2b712014-10-09 20:29:07229 upload_data_stream_.reset(
olli.raula6df48b2a2015-11-26 07:40:22230 new ElementsUploadDataStream(std::move(element_readers), 0));
[email protected]50ca73e22013-09-30 00:37:50231 request_.method = "POST";
rchf114d982015-10-21 01:34:56232 request_.url = GURL("https://test.example.com/");
[email protected]50ca73e22013-09-30 00:37:50233 request_.upload_data_stream = upload_data_stream_.get();
234 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
235 }
236
237 // Checks that |consumer| completed and received |status_line| and |body|.
238 void CheckResponse(const TestTransactionConsumer& consumer,
239 const std::string& status_line,
240 const std::string& body) {
241 ASSERT_TRUE(consumer.is_done());
rchf114d982015-10-21 01:34:56242 ASSERT_EQ(OK, consumer.error());
rjshaded5ced072015-12-18 19:26:02243 EXPECT_EQ(status_line, consumer.response_info()->headers->GetStatusLine());
[email protected]50ca73e22013-09-30 00:37:50244 EXPECT_EQ(body, consumer.content());
245 }
246
247 scoped_ptr<MockHostResolver> host_resolver_impl_;
248 MappedHostResolver host_resolver_;
249 MockCertVerifier cert_verifier_;
nharperd5cddca2016-02-27 03:37:52250 scoped_ptr<ChannelIDService> channel_id_service_;
[email protected]50ca73e22013-09-30 00:37:50251 TransportSecurityState transport_security_state_;
rtenneti052774e2015-11-24 21:00:12252 scoped_ptr<CTVerifier> cert_transparency_verifier_;
[email protected]50ca73e22013-09-30 00:37:50253 scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
254 scoped_ptr<ProxyService> proxy_service_;
255 scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
256 HttpServerPropertiesImpl http_server_properties;
257 HttpNetworkSession::Params params_;
258 scoped_ptr<TestTransactionFactory> transaction_factory_;
259 HttpRequestInfo request_;
260 std::string request_body_;
261 scoped_ptr<UploadDataStream> upload_data_stream_;
262 scoped_ptr<ServerThread> server_thread_;
263 IPEndPoint server_address_;
264 std::string server_hostname_;
265 QuicConfig server_config_;
nharperd5cddca2016-02-27 03:37:52266 QuicCryptoServerConfig::ConfigOptions server_config_options_;
[email protected]50ca73e22013-09-30 00:37:50267 bool server_started_;
268 bool strike_register_no_startup_period_;
269};
270
rchf37ccc782016-01-31 05:13:50271INSTANTIATE_TEST_CASE_P(Tests,
272 QuicEndToEndTest,
273 ::testing::ValuesIn(GetTestParams()));
274
275TEST_P(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
[email protected]50ca73e22013-09-30 00:37:50276 std::string response(10 * 1024, 'x');
277
rchaa7859a12015-03-23 22:50:08278 AddToCache(request_.url.PathForRequest(), 200, "OK", response);
[email protected]50ca73e22013-09-30 00:37:50279
280 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
281 transaction_factory_.get());
282 consumer.Start(&request_, BoundNetLog());
283
284 // Will terminate when the last consumer completes.
285 base::MessageLoop::current()->Run();
286
bnc84e7fb52015-12-02 11:50:02287 CheckResponse(consumer, "HTTP/1.1 200", response);
[email protected]50ca73e22013-09-30 00:37:50288}
289
nharperd5cddca2016-02-27 03:37:52290TEST_P(QuicEndToEndTest, TokenBinding) {
291 // Enable token binding and re-initialize the TestTransactionFactory.
292 params_.enable_token_binding = true;
293 transaction_factory_.reset(new TestTransactionFactory(params_));
294
295 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
296
297 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
298 transaction_factory_.get());
299 consumer.Start(&request_, BoundNetLog());
300
301 // Will terminate when the last consumer completes.
302 base::MessageLoop::current()->Run();
303
304 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
305 HttpRequestHeaders headers;
306 ASSERT_TRUE(consumer.transaction()->GetFullRequestHeaders(&headers));
307 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
308}
309
rtennetie3b666d2016-01-08 05:07:28310// crbug.com/559173
311#if defined(THREAD_SANITIZER)
rchf37ccc782016-01-31 05:13:50312TEST_P(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28313#else
rchf37ccc782016-01-31 05:13:50314TEST_P(QuicEndToEndTest, LargePostWithNoPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28315#endif
rtenneti97238d662015-10-23 16:16:58316 InitializePostRequest(1024 * 1024);
[email protected]50ca73e22013-09-30 00:37:50317
rchaa7859a12015-03-23 22:50:08318 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50319
320 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
321 transaction_factory_.get());
322 consumer.Start(&request_, BoundNetLog());
323
324 // Will terminate when the last consumer completes.
325 base::MessageLoop::current()->Run();
326
bnc84e7fb52015-12-02 11:50:02327 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50328}
329
rtennetie3b666d2016-01-08 05:07:28330// crbug.com/559173
331#if defined(THREAD_SANITIZER)
rchf37ccc782016-01-31 05:13:50332TEST_P(QuicEndToEndTest, DISABLED_LargePostWithPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28333#else
rchf37ccc782016-01-31 05:13:50334TEST_P(QuicEndToEndTest, LargePostWithPacketLoss) {
rtennetie3b666d2016-01-08 05:07:28335#endif
[email protected]50ca73e22013-09-30 00:37:50336 // FLAGS_fake_packet_loss_percentage = 30;
337 InitializePostRequest(1024 * 1024);
338
339 const char kResponseBody[] = "some really big response body";
rchaa7859a12015-03-23 22:50:08340 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50341
342 TestTransactionConsumer consumer(DEFAULT_PRIORITY,
343 transaction_factory_.get());
344 consumer.Start(&request_, BoundNetLog());
345
346 // Will terminate when the last consumer completes.
347 base::MessageLoop::current()->Run();
348
bnc84e7fb52015-12-02 11:50:02349 CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50350}
351
zhaoqinf60fa492015-09-30 16:24:08352// crbug.com/536845
353#if defined(THREAD_SANITIZER)
rchf37ccc782016-01-31 05:13:50354TEST_P(QuicEndToEndTest, DISABLED_UberTest) {
zhaoqinf60fa492015-09-30 16:24:08355#else
rchf37ccc782016-01-31 05:13:50356TEST_P(QuicEndToEndTest, UberTest) {
zhaoqinf60fa492015-09-30 16:24:08357#endif
[email protected]50ca73e22013-09-30 00:37:50358 // FLAGS_fake_packet_loss_percentage = 30;
359
360 const char kResponseBody[] = "some really big response body";
rchaa7859a12015-03-23 22:50:08361 AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50362
363 std::vector<TestTransactionConsumer*> consumers;
364 size_t num_requests = 100;
365 for (size_t i = 0; i < num_requests; ++i) {
rjshaded5ced072015-12-18 19:26:02366 TestTransactionConsumer* consumer = new TestTransactionConsumer(
367 DEFAULT_PRIORITY, transaction_factory_.get());
368 consumers.push_back(consumer);
369 consumer->Start(&request_, BoundNetLog());
[email protected]50ca73e22013-09-30 00:37:50370 }
371
372 // Will terminate when the last consumer completes.
373 base::MessageLoop::current()->Run();
374
375 for (size_t i = 0; i < num_requests; ++i) {
bnc84e7fb52015-12-02 11:50:02376 CheckResponse(*consumers[i], "HTTP/1.1 200", kResponseBody);
[email protected]50ca73e22013-09-30 00:37:50377 }
378 STLDeleteElements(&consumers);
379}
380
381} // namespace test
382} // namespace net