| // Copyright 2018 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 "base/macros.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/test/scoped_task_environment.h" |
| #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" |
| #include "net/url_request/url_request_context.h" |
| #include "net/url_request/url_request_context_builder.h" |
| #include "services/network/cors/cors_url_loader_factory.h" |
| #include "services/network/network_context.h" |
| #include "services/network/network_service.h" |
| #include "services/network/public/cpp/features.h" |
| #include "services/network/public/cpp/resource_request.h" |
| #include "services/network/public/mojom/url_loader.mojom.h" |
| #include "services/network/public/mojom/url_loader_factory.mojom.h" |
| #include "services/network/resource_scheduler.h" |
| #include "services/network/resource_scheduler_client.h" |
| #include "services/network/test/test_url_loader_client.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace network { |
| namespace cors { |
| |
| namespace { |
| |
| constexpr int kProcessId = 123; |
| constexpr int kRequestId = 456; |
| constexpr int kRouteId = 789; |
| |
| } // namespace |
| |
| class CorsURLLoaderFactoryTest : public testing::Test { |
| public: |
| CorsURLLoaderFactoryTest() |
| : scoped_task_environment_( |
| base::test::ScopedTaskEnvironment::MainThreadType::IO), |
| resource_scheduler_(true) { |
| net::URLRequestContextBuilder context_builder; |
| context_builder.set_proxy_resolution_service( |
| net::ProxyResolutionService::CreateDirect()); |
| url_request_context_ = context_builder.Build(); |
| } |
| |
| protected: |
| // testing::Test implementation. |
| void SetUp() override { |
| feature_list_.InitAndEnableFeature(features::kOutOfBlinkCors); |
| |
| network_service_ = NetworkService::CreateForTesting(); |
| |
| auto context_params = mojom::NetworkContextParams::New(); |
| // Use a fixed proxy config, to avoid dependencies on local network |
| // configuration. |
| context_params->initial_proxy_config = |
| net::ProxyConfigWithAnnotation::CreateDirect(); |
| network_context_ = std::make_unique<NetworkContext>( |
| network_service_.get(), mojo::MakeRequest(&network_context_ptr_), |
| std::move(context_params)); |
| |
| auto factory_params = network::mojom::URLLoaderFactoryParams::New(); |
| factory_params->process_id = kProcessId; |
| auto resource_scheduler_client = |
| base::MakeRefCounted<ResourceSchedulerClient>( |
| kProcessId, kRouteId, &resource_scheduler_, |
| url_request_context_->network_quality_estimator()); |
| cors_url_loader_factory_ = std::make_unique<CorsURLLoaderFactory>( |
| network_context_.get(), std::move(factory_params), |
| resource_scheduler_client, |
| mojo::MakeRequest(&cors_url_loader_factory_ptr_), &origin_access_list_, |
| nullptr); |
| } |
| |
| void CreateLoaderAndStart(const ResourceRequest& request) { |
| cors_url_loader_factory_->CreateLoaderAndStart( |
| mojo::MakeRequest(&url_loader_), kRouteId, kRequestId, |
| mojom::kURLLoadOptionNone, request, |
| test_cors_loader_client_.CreateInterfacePtr(), |
| net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); |
| } |
| |
| void ResetFactory() { cors_url_loader_factory_.reset(); } |
| |
| private: |
| // Testing instance to enable kOutOfBlinkCors feature. |
| base::test::ScopedFeatureList feature_list_; |
| |
| // Test environment. |
| base::test::ScopedTaskEnvironment scoped_task_environment_; |
| std::unique_ptr<net::URLRequestContext> url_request_context_; |
| ResourceScheduler resource_scheduler_; |
| std::unique_ptr<NetworkService> network_service_; |
| std::unique_ptr<NetworkContext> network_context_; |
| mojom::NetworkContextPtr network_context_ptr_; |
| |
| // CorsURLLoaderFactory instance under tests. |
| std::unique_ptr<mojom::URLLoaderFactory> cors_url_loader_factory_; |
| mojom::URLLoaderFactoryPtr cors_url_loader_factory_ptr_; |
| |
| // Holds URLLoaderPtr that CreateLoaderAndStart() creates. |
| mojom::URLLoaderPtr url_loader_; |
| |
| // TestURLLoaderClient that records callback activities. |
| TestURLLoaderClient test_cors_loader_client_; |
| |
| // Holds for allowed origin access lists. |
| OriginAccessList origin_access_list_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CorsURLLoaderFactoryTest); |
| }; |
| |
| // Regression test for https://crbug.com/906305. |
| TEST_F(CorsURLLoaderFactoryTest, DestructionOrder) { |
| ResourceRequest request; |
| GURL url("http://localhost"); |
| request.fetch_request_mode = mojom::FetchRequestMode::kNoCors; |
| request.fetch_credentials_mode = mojom::FetchCredentialsMode::kOmit; |
| request.allow_credentials = false; |
| request.method = net::HttpRequestHeaders::kGetMethod; |
| request.url = url; |
| request.request_initiator = url::Origin::Create(url); |
| |
| // As of r609458 setting |keepalive| to true was triggerring a dereference of |
| // |factory_params_| in the destructor of network::URLLoader. This |
| // dereference assumes that the network::URLLoaderFactory (which keeps |
| // |factory_params_| alive) lives longer than the network::URLLoaders created |
| // via the factory (which necessitates being careful with the destruction |
| // order of fields of network::cors::CorsURLLoaderFactory which owns both |
| // network::URLLoaderFactory and the network::URLLoaders it creates). |
| request.keepalive = true; |
| |
| // Create a loader and immediately (while the loader is still stored in |
| // CorsURLLoaderFactory::loaders_ / not released via test_cors_loader_client_) |
| // destroy the factory. If ASAN doesn't complain then the test passes. |
| CreateLoaderAndStart(request); |
| ResetFactory(); |
| } |
| |
| } // namespace cors |
| } // namespace network |