transitional_url_loader_factory_owner.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2018 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. #include "services/network/transitional_url_loader_factory_owner.h"
  5. #include "base/bind.h"
  6. #include "base/memory/ptr_util.h"
  7. #include "base/memory/ref_counted.h"
  8. #include "base/memory/ref_counted_delete_on_sequence.h"
  9. #include "base/no_destructor.h"
  10. #include "base/synchronization/atomic_flag.h"
  11. #include "net/url_request/url_request_context_getter.h"
  12. #include "services/network/network_context.h"
  13. #include "services/network/public/cpp/shared_url_loader_factory.h"
  14. #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
  15. namespace network {
  16. // Portion of TransitionalURLLoaderFactoryOwner that lives on the network
  17. // task runner associated with the URLRequestContextGetter.
  18. class TransitionalURLLoaderFactoryOwner::Core {
  19. public:
  20. Core(scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
  21. : url_request_context_getter_(std::move(url_request_context_getter)),
  22. task_runner_(url_request_context_getter_->GetNetworkTaskRunner()) {}
  23. void CreateNetworkContext(
  24. mojo::PendingReceiver<mojom::NetworkContext> receiver) {
  25. if (task_runner_->RunsTasksInCurrentSequence()) {
  26. // This must be synchronous since in same-runner case deletes are
  27. // synchronous as well.
  28. CreateNetworkContextOnNetworkThread(std::move(receiver));
  29. } else {
  30. // Unretained is safe since cross-thread deletes will also be posted.
  31. task_runner_->PostTask(
  32. FROM_HERE,
  33. base::BindOnce(&Core::CreateNetworkContextOnNetworkThread,
  34. base::Unretained(this), std::move(receiver)));
  35. }
  36. }
  37. static void DeleteOnRightThread(std::unique_ptr<Core> instance) {
  38. scoped_refptr<base::SequencedTaskRunner> task_runner =
  39. instance->task_runner_;
  40. if (!task_runner->RunsTasksInCurrentSequence())
  41. task_runner->DeleteSoon(FROM_HERE, std::move(instance));
  42. // otherwise |instance| going out of scope will do the right thing.
  43. }
  44. private:
  45. friend struct std::default_delete<Core>;
  46. ~Core() {
  47. DCHECK(url_request_context_getter_->GetURLRequestContext());
  48. DCHECK(task_runner_->RunsTasksInCurrentSequence());
  49. }
  50. void CreateNetworkContextOnNetworkThread(
  51. mojo::PendingReceiver<mojom::NetworkContext> receiver) {
  52. network_context_ = std::make_unique<network::NetworkContext>(
  53. nullptr /* network_service */, std::move(receiver),
  54. url_request_context_getter_->GetURLRequestContext(),
  55. /*cors_exempt_header_list=*/std::vector<std::string>());
  56. }
  57. scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
  58. scoped_refptr<base::SequencedTaskRunner> task_runner_;
  59. std::unique_ptr<network::NetworkContext> network_context_;
  60. };
  61. TransitionalURLLoaderFactoryOwner::TransitionalURLLoaderFactoryOwner(
  62. scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
  63. : core_(std::make_unique<Core>(std::move(url_request_context_getter))) {
  64. DCHECK(!disallowed_in_process().IsSet());
  65. }
  66. TransitionalURLLoaderFactoryOwner::~TransitionalURLLoaderFactoryOwner() {
  67. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  68. DCHECK(!disallowed_in_process().IsSet());
  69. if (shared_url_loader_factory_)
  70. shared_url_loader_factory_->Detach();
  71. Core::DeleteOnRightThread(std::move(core_));
  72. }
  73. scoped_refptr<network::SharedURLLoaderFactory>
  74. TransitionalURLLoaderFactoryOwner::GetURLLoaderFactory() {
  75. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  76. DCHECK(!disallowed_in_process().IsSet());
  77. if (!shared_url_loader_factory_) {
  78. core_->CreateNetworkContext(
  79. network_context_remote_.BindNewPipeAndPassReceiver());
  80. auto url_loader_factory_params =
  81. network::mojom::URLLoaderFactoryParams::New();
  82. url_loader_factory_params->process_id = mojom::kBrowserProcessId;
  83. url_loader_factory_params->is_corb_enabled = false;
  84. network_context_remote_->CreateURLLoaderFactory(
  85. url_loader_factory_.BindNewPipeAndPassReceiver(),
  86. std::move(url_loader_factory_params));
  87. shared_url_loader_factory_ =
  88. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  89. url_loader_factory_.get());
  90. }
  91. return shared_url_loader_factory_;
  92. }
  93. network::mojom::NetworkContext*
  94. TransitionalURLLoaderFactoryOwner::GetNetworkContext() {
  95. GetURLLoaderFactory();
  96. return network_context_remote_.get();
  97. }
  98. void TransitionalURLLoaderFactoryOwner::DisallowUsageInProcess() {
  99. disallowed_in_process().Set();
  100. }
  101. base::AtomicFlag& TransitionalURLLoaderFactoryOwner::disallowed_in_process() {
  102. static base::NoDestructor<base::AtomicFlag> instance;
  103. return *instance;
  104. }
  105. } // namespace network