• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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