123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <memory>
- #include <ostream>
- #include <utility>
- #include <vector>
- #include "base/compiler_specific.h"
- #include "base/memory/ptr_util.h"
- #include "base/run_loop.h"
- #include "base/strings/string_number_conversions.h"
- #include "net/base/completion_once_callback.h"
- #include "net/base/elements_upload_data_stream.h"
- #include "net/base/ip_address.h"
- #include "net/base/test_completion_callback.h"
- #include "net/base/upload_bytes_element_reader.h"
- #include "net/base/upload_data_stream.h"
- #include "net/cert/ct_policy_enforcer.h"
- #include "net/cert/mock_cert_verifier.h"
- #include "net/cert/multi_log_ct_verifier.h"
- #include "net/dns/mapped_host_resolver.h"
- #include "net/dns/mock_host_resolver.h"
- #include "net/http/http_auth_handler_factory.h"
- #include "net/http/http_network_session.h"
- #include "net/http/http_network_transaction.h"
- #include "net/http/http_server_properties.h"
- #include "net/http/http_transaction_test_util.h"
- #include "net/http/transport_security_state.h"
- #include "net/log/net_log_with_source.h"
- #include "net/proxy_resolution/configured_proxy_resolution_service.h"
- #include "net/quic/crypto_test_utils_chromium.h"
- #include "net/quic/quic_context.h"
- #include "net/socket/client_socket_factory.h"
- #include "net/ssl/ssl_config_service_defaults.h"
- #include "net/test/cert_test_util.h"
- #include "net/test/gtest_util.h"
- #include "net/test/test_data_directory.h"
- #include "net/test/test_with_task_environment.h"
- #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
- #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
- #include "net/third_party/quiche/src/quiche/quic/tools/quic_memory_cache_backend.h"
- #include "net/tools/quic/quic_simple_server.h"
- #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "testing/platform_test.h"
- namespace net {
- using test::IsOk;
- namespace test {
- namespace {
- const char kResponseBody[] = "some arbitrary response body";
- // Factory for creating HttpTransactions, used by TestTransactionConsumer.
- class TestTransactionFactory : public HttpTransactionFactory {
- public:
- explicit TestTransactionFactory(
- const HttpNetworkSessionParams& session_params,
- const HttpNetworkSessionContext& session_context)
- : session_(std::make_unique<HttpNetworkSession>(session_params,
- session_context)) {}
- ~TestTransactionFactory() override = default;
- // HttpTransactionFactory methods
- int CreateTransaction(RequestPriority priority,
- std::unique_ptr<HttpTransaction>* trans) override {
- *trans = std::make_unique<HttpNetworkTransaction>(priority, session_.get());
- return OK;
- }
- HttpCache* GetCache() override { return nullptr; }
- HttpNetworkSession* GetSession() override { return session_.get(); }
- private:
- std::unique_ptr<HttpNetworkSession> session_;
- };
- } // namespace
- class QuicEndToEndTest : public ::testing::Test, public WithTaskEnvironment {
- protected:
- QuicEndToEndTest()
- : host_resolver_(CreateResolverImpl()),
- ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
- proxy_resolution_service_(
- ConfiguredProxyResolutionService::CreateDirect()),
- auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()) {
- request_.method = "GET";
- request_.url = GURL("https://test.example.com/");
- request_.load_flags = 0;
- request_.traffic_annotation =
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
- session_params_.enable_quic = true;
- session_context_.client_socket_factory =
- ClientSocketFactory::GetDefaultFactory();
- session_context_.quic_context = &quic_context_;
- session_context_.host_resolver = &host_resolver_;
- session_context_.cert_verifier = &cert_verifier_;
- session_context_.transport_security_state = &transport_security_state_;
- session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
- session_context_.proxy_resolution_service = proxy_resolution_service_.get();
- session_context_.ssl_config_service = ssl_config_service_.get();
- session_context_.http_auth_handler_factory = auth_handler_factory_.get();
- session_context_.http_server_properties = &http_server_properties_;
- CertVerifyResult verify_result;
- verify_result.verified_cert =
- ImportCertFromFile(GetTestCertsDirectory(), "quic-chain.pem");
- cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
- "test.example.com", verify_result,
- OK);
- }
- // Creates a mock host resolver in which test.example.com
- // resolves to localhost.
- static std::unique_ptr<MockHostResolver> CreateResolverImpl() {
- auto resolver = std::make_unique<MockHostResolver>();
- resolver->rules()->AddRule("test.example.com", "127.0.0.1");
- return resolver;
- }
- void SetUp() override {
- StartServer();
- // Use a mapped host resolver so that request for test.example.com (port 80)
- // reach the server running on localhost.
- std::string map_rule =
- "MAP test.example.com test.example.com:" +
- base::NumberToString(server_->server_address().port());
- EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));
- // To simplify the test, and avoid the race with the HTTP request, we force
- // QUIC for these requests.
- quic_context_.params()->origins_to_force_quic_on.insert(
- HostPortPair::FromString("test.example.com:443"));
- transaction_factory_ = std::make_unique<TestTransactionFactory>(
- session_params_, session_context_);
- }
- void TearDown() override {}
- // Starts the QUIC server listening on a random port.
- void StartServer() {
- server_address_ = IPEndPoint(IPAddress(127, 0, 0, 1), 0);
- server_config_.SetInitialStreamFlowControlWindowToSend(
- quic::test::kInitialStreamFlowControlWindowForTest);
- server_config_.SetInitialSessionFlowControlWindowToSend(
- quic::test::kInitialSessionFlowControlWindowForTest);
- server_ = std::make_unique<QuicSimpleServer>(
- net::test::ProofSourceForTestingChromium(), server_config_,
- server_config_options_, quic::AllSupportedVersions(),
- &memory_cache_backend_);
- server_->Listen(server_address_);
- server_address_ = server_->server_address();
- server_->StartReading();
- server_started_ = true;
- }
- // Adds an entry to the cache used by the QUIC server to serve
- // responses.
- void AddToCache(absl::string_view path,
- int response_code,
- absl::string_view response_detail,
- absl::string_view body) {
- memory_cache_backend_.AddSimpleResponse("test.example.com", path,
- response_code, body);
- }
- // Populates |request_body_| with |length_| ASCII bytes.
- void GenerateBody(size_t length) {
- request_body_.clear();
- request_body_.reserve(length);
- for (size_t i = 0; i < length; ++i) {
- request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
- }
- }
- // Initializes |request_| for a post of |length| bytes.
- void InitializePostRequest(size_t length) {
- GenerateBody(length);
- std::vector<std::unique_ptr<UploadElementReader>> element_readers;
- element_readers.push_back(std::make_unique<UploadBytesElementReader>(
- request_body_.data(), request_body_.length()));
- upload_data_stream_ = std::make_unique<ElementsUploadDataStream>(
- std::move(element_readers), 0);
- request_.method = "POST";
- request_.url = GURL("https://test.example.com/");
- request_.upload_data_stream = upload_data_stream_.get();
- ASSERT_THAT(request_.upload_data_stream->Init(CompletionOnceCallback(),
- NetLogWithSource()),
- IsOk());
- }
- // Checks that |consumer| completed and received |status_line| and |body|.
- void CheckResponse(const TestTransactionConsumer& consumer,
- const std::string& status_line,
- const std::string& body) {
- ASSERT_TRUE(consumer.is_done());
- ASSERT_THAT(consumer.error(), IsOk());
- EXPECT_EQ(status_line, consumer.response_info()->headers->GetStatusLine());
- EXPECT_EQ(body, consumer.content());
- }
- QuicContext quic_context_;
- MappedHostResolver host_resolver_;
- MockCertVerifier cert_verifier_;
- TransportSecurityState transport_security_state_;
- DefaultCTPolicyEnforcer ct_policy_enforcer_;
- std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
- std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
- std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
- HttpServerProperties http_server_properties_;
- HttpNetworkSessionParams session_params_;
- HttpNetworkSessionContext session_context_;
- std::unique_ptr<TestTransactionFactory> transaction_factory_;
- HttpRequestInfo request_;
- std::string request_body_;
- std::unique_ptr<UploadDataStream> upload_data_stream_;
- std::unique_ptr<QuicSimpleServer> server_;
- quic::QuicMemoryCacheBackend memory_cache_backend_;
- IPEndPoint server_address_;
- std::string server_hostname_;
- quic::QuicConfig server_config_;
- quic::QuicCryptoServerConfig::ConfigOptions server_config_options_;
- bool server_started_;
- bool strike_register_no_startup_period_ = false;
- };
- TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
- std::string response(10 * 1024, 'x');
- AddToCache(request_.url.PathForRequest(), 200, "OK", response);
- TestTransactionConsumer consumer(DEFAULT_PRIORITY,
- transaction_factory_.get());
- consumer.Start(&request_, NetLogWithSource());
- // Will terminate when the last consumer completes.
- base::RunLoop().Run();
- CheckResponse(consumer, "HTTP/1.1 200", response);
- }
- // crbug.com/559173
- #if defined(THREAD_SANITIZER)
- TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
- #else
- TEST_F(QuicEndToEndTest, LargePostWithNoPacketLoss) {
- #endif
- InitializePostRequest(1024 * 1024);
- AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
- TestTransactionConsumer consumer(DEFAULT_PRIORITY,
- transaction_factory_.get());
- consumer.Start(&request_, NetLogWithSource());
- // Will terminate when the last consumer completes.
- base::RunLoop().Run();
- CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
- }
- // crbug.com/559173
- #if defined(THREAD_SANITIZER)
- TEST_F(QuicEndToEndTest, DISABLED_LargePostWithPacketLoss) {
- #else
- TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
- #endif
- // FLAGS_fake_packet_loss_percentage = 30;
- InitializePostRequest(1024 * 1024);
- AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
- TestTransactionConsumer consumer(DEFAULT_PRIORITY,
- transaction_factory_.get());
- consumer.Start(&request_, NetLogWithSource());
- // Will terminate when the last consumer completes.
- base::RunLoop().Run();
- CheckResponse(consumer, "HTTP/1.1 200", kResponseBody);
- }
- // crbug.com/536845
- #if defined(THREAD_SANITIZER)
- TEST_F(QuicEndToEndTest, DISABLED_UberTest) {
- #else
- TEST_F(QuicEndToEndTest, UberTest) {
- #endif
- // FLAGS_fake_packet_loss_percentage = 30;
- AddToCache(request_.url.PathForRequest(), 200, "OK", kResponseBody);
- std::vector<std::unique_ptr<TestTransactionConsumer>> consumers;
- for (size_t i = 0; i < 100; ++i) {
- TestTransactionConsumer* consumer = new TestTransactionConsumer(
- DEFAULT_PRIORITY, transaction_factory_.get());
- consumers.push_back(base::WrapUnique(consumer));
- consumer->Start(&request_, NetLogWithSource());
- }
- // Will terminate when the last consumer completes.
- base::RunLoop().Run();
- for (const auto& consumer : consumers)
- CheckResponse(*consumer.get(), "HTTP/1.1 200", kResponseBody);
- }
- } // namespace test
- } // namespace net
|