1 // 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 
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 "net/base/completion_once_callback.h"
15 #include "net/base/elements_upload_data_stream.h"
16 #include "net/base/ip_address.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/base/upload_bytes_element_reader.h"
19 #include "net/base/upload_data_stream.h"
20 #include "net/cert/ct_policy_enforcer.h"
21 #include "net/cert/mock_cert_verifier.h"
22 #include "net/cert/multi_log_ct_verifier.h"
23 #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.h"
29 #include "net/http/http_transaction_test_util.h"
30 #include "net/http/transport_security_state.h"
31 #include "net/log/net_log_with_source.h"
32 #include "net/proxy_resolution/configured_proxy_resolution_service.h"
33 #include "net/quic/quic_context.h"
34 #include "net/ssl/ssl_config_service_defaults.h"
35 #include "net/test/cert_test_util.h"
36 #include "net/test/gtest_util.h"
37 #include "net/test/test_data_directory.h"
38 #include "net/test/test_with_task_environment.h"
39 #include "net/third_party/quiche/src/common/platform/api/quiche_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"
43 #include "net/tools/quic/quic_simple_server.h"
44 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
47 #include "testing/platform_test.h"
48 
49 namespace net {
50 
51 using test::IsOk;
52 
53 namespace test {
54 
55 namespace {
56 
57 const char kResponseBody[] = "some arbitrary response body";
58 
59 // Factory for creating HttpTransactions, used by TestTransactionConsumer.
60 class TestTransactionFactory : public HttpTransactionFactory {
61  public:
TestTransactionFactory(const HttpNetworkSession::Params & session_params,const HttpNetworkSession::Context & session_context)62   explicit TestTransactionFactory(
63       const HttpNetworkSession::Params& session_params,
64       const HttpNetworkSession::Context& session_context)
65       : session_(new HttpNetworkSession(session_params, session_context)) {}
66 
~TestTransactionFactory()67   ~TestTransactionFactory() override {}
68 
69   // HttpTransactionFactory methods
CreateTransaction(RequestPriority priority,std::unique_ptr<HttpTransaction> * trans)70   int CreateTransaction(RequestPriority priority,
71                         std::unique_ptr<HttpTransaction>* trans) override {
72     trans->reset(new HttpNetworkTransaction(priority, session_.get()));
73     return OK;
74   }
75 
GetCache()76   HttpCache* GetCache() override { return nullptr; }
77 
GetSession()78   HttpNetworkSession* GetSession() override { return session_.get(); }
79 
80  private:
81   std::unique_ptr<HttpNetworkSession> session_;
82 };
83 
84 }  // namespace
85 
86 class QuicEndToEndTest : public ::testing::Test, public WithTaskEnvironment {
87  protected:
QuicEndToEndTest()88   QuicEndToEndTest()
89       : host_resolver_impl_(CreateResolverImpl()),
90         host_resolver_(std::move(host_resolver_impl_)),
91         cert_transparency_verifier_(new MultiLogCTVerifier()),
92         ssl_config_service_(new SSLConfigServiceDefaults),
93         proxy_resolution_service_(
94             ConfiguredProxyResolutionService::CreateDirect()),
95         auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
96         strike_register_no_startup_period_(false) {
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_.quic_context = &quic_context_;
106     session_context_.host_resolver = &host_resolver_;
107     session_context_.cert_verifier = &cert_verifier_;
108     session_context_.transport_security_state = &transport_security_state_;
109     session_context_.cert_transparency_verifier =
110         cert_transparency_verifier_.get();
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 MockHostResolver* CreateResolverImpl() {
128     MockHostResolver* resolver = new 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_.reset(
149         new TestTransactionFactory(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_.reset(new QuicSimpleServer(
162         quic::test::crypto_test_utils::ProofSourceForTesting(), server_config_,
163         server_config_options_, quic::AllSupportedVersions(),
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(quiche::QuicheStringPiece path,int response_code,quiche::QuicheStringPiece response_detail,quiche::QuicheStringPiece body)173   void AddToCache(quiche::QuicheStringPiece path,
174                   int response_code,
175                   quiche::QuicheStringPiece response_detail,
176                   quiche::QuicheStringPiece 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_.reset(
197         new ElementsUploadDataStream(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   std::unique_ptr<MockHostResolver> host_resolver_impl_;
218   MappedHostResolver host_resolver_;
219   MockCertVerifier cert_verifier_;
220   TransportSecurityState transport_security_state_;
221   std::unique_ptr<CTVerifier> cert_transparency_verifier_;
222   DefaultCTPolicyEnforcer ct_policy_enforcer_;
223   std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
224   std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
225   std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
226   HttpServerProperties http_server_properties_;
227   HttpNetworkSession::Params session_params_;
228   HttpNetworkSession::Context session_context_;
229   std::unique_ptr<TestTransactionFactory> transaction_factory_;
230   HttpRequestInfo request_;
231   std::string request_body_;
232   std::unique_ptr<UploadDataStream> upload_data_stream_;
233   std::unique_ptr<QuicSimpleServer> server_;
234   quic::QuicMemoryCacheBackend memory_cache_backend_;
235   IPEndPoint server_address_;
236   std::string server_hostname_;
237   quic::QuicConfig server_config_;
238   quic::QuicCryptoServerConfig::ConfigOptions server_config_options_;
239   bool server_started_;
240   bool strike_register_no_startup_period_;
241 };
242 
TEST_F(QuicEndToEndTest,LargeGetWithNoPacketLoss)243 TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
244   std::string response(10 * 1024, 'x');
245 
246   AddToCache(request_.url.PathForRequest(), 200, "OK", response);
247 
248   TestTransactionConsumer consumer(DEFAULT_PRIORITY,
249                                    transaction_factory_.get());
250   consumer.Start(&request_, NetLogWithSource());
251 
252   // Will terminate when the last consumer completes.
253   base::RunLoop().Run();
254 
255   CheckResponse(consumer, "HTTP/1.1 200", response);
256 }
257 
258 // crbug.com/559173
259 #if defined(THREAD_SANITIZER)
TEST_F(QuicEndToEndTest,DISABLED_LargePostWithNoPacketLoss)260 TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
261 #else
262 TEST_F(QuicEndToEndTest, LargePostWithNoPacketLoss) {
263 #endif
264   InitializePostRequest(1024 * 1024);
265 
266   AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
267 
268   TestTransactionConsumer consumer(DEFAULT_PRIORITY,
269                                    transaction_factory_.get());
270   consumer.Start(&request_, NetLogWithSource());
271 
272   // Will terminate when the last consumer completes.
273   base::RunLoop().Run();
274 
275   CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
276 }
277 
278 // crbug.com/559173
279 #if defined(THREAD_SANITIZER)
280 TEST_F(QuicEndToEndTest, DISABLED_LargePostWithPacketLoss) {
281 #else
282 TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
283 #endif
284   // FLAGS_fake_packet_loss_percentage = 30;
285   InitializePostRequest(1024 * 1024);
286 
287   const char kResponseBody[] = "some really big response body";
288   AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
289 
290   TestTransactionConsumer consumer(DEFAULT_PRIORITY,
291                                    transaction_factory_.get());
292   consumer.Start(&request_, NetLogWithSource());
293 
294   // Will terminate when the last consumer completes.
295   base::RunLoop().Run();
296 
297   CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
298 }
299 
300 // crbug.com/536845
301 #if defined(THREAD_SANITIZER)
302 TEST_F(QuicEndToEndTest, DISABLED_UberTest) {
303 #else
304 TEST_F(QuicEndToEndTest, UberTest) {
305 #endif
306   // FLAGS_fake_packet_loss_percentage = 30;
307 
308   const char kResponseBody[] = "some really big response body";
309   AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
310 
311   std::vector<std::unique_ptr<TestTransactionConsumer>> consumers;
312   for (size_t i = 0; i < 100; ++i) {
313     TestTransactionConsumer* consumer = new TestTransactionConsumer(
314         DEFAULT_PRIORITY, transaction_factory_.get());
315     consumers.push_back(base::WrapUnique(consumer));
316     consumer->Start(&request_, NetLogWithSource());
317   }
318 
319   // Will terminate when the last consumer completes.
320   base::RunLoop().Run();
321 
322   for (const auto& consumer : consumers)
323     CheckResponse(*consumer.get(), "HTTP/1.1 200", kResponseBody);
324 }
325 
326 }  // namespace test
327 }  // namespace net
328