diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index dafb003465d9..daccf443927a 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -5,6 +5,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/atom_browser_context.h" +#include "atom/browser/request_context_delegate.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/value_converter.h" @@ -253,9 +254,10 @@ void SetCookieOnIO(scoped_refptr getter, Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context) : browser_context_(browser_context) { Init(isolate); - auto subscription = browser_context->RegisterCookieChangeCallback( - base::Bind(&Cookies::OnCookieChanged, base::Unretained(this))); - browser_context->set_cookie_change_subscription(std::move(subscription)); + cookie_change_subscription_ = + browser_context->GetRequestContextDelegate() + ->RegisterCookieChangeCallback( + base::Bind(&Cookies::OnCookieChanged, base::Unretained(this))); } Cookies::~Cookies() {} diff --git a/atom/browser/api/atom_api_cookies.h b/atom/browser/api/atom_api_cookies.h index 403e22623302..8a83a64ca101 100644 --- a/atom/browser/api/atom_api_cookies.h +++ b/atom/browser/api/atom_api_cookies.h @@ -9,7 +9,7 @@ #include "atom/browser/api/trackable_object.h" #include "atom/browser/net/cookie_details.h" -#include "base/callback.h" +#include "base/callback_list.h" #include "native_mate/handle.h" #include "net/cookies/canonical_cookie.h" @@ -59,6 +59,8 @@ class Cookies : public mate::TrackableObject { void OnCookieChanged(const CookieDetails*); private: + std::unique_ptr::Subscription> + cookie_change_subscription_; scoped_refptr browser_context_; DISALLOW_COPY_AND_ASSIGN(Cookies); diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index ab5e34872c6e..deaf680c996c 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -78,13 +78,13 @@ class Protocol : public mate::TrackableObject { net::URLRequest* request, net::NetworkDelegate* network_delegate) const override { RequestJob* request_job = new RequestJob(request, network_delegate); - request_job->SetHandlerInfo(isolate_, request_context_.get(), handler_); + request_job->SetHandlerInfo(isolate_, request_context_, handler_); return request_job; } private: v8::Isolate* isolate_; - scoped_refptr request_context_; + net::URLRequestContextGetter* request_context_; Protocol::Handler handler_; DISALLOW_COPY_AND_ASSIGN(CustomProtocolHandler); diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 2ca8ae0e26dd..658f913bb60b 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -244,7 +244,7 @@ class ResolveProxyHelper { : callback_(callback), original_thread_(base::ThreadTaskRunnerHandle::Get()) { scoped_refptr context_getter = - browser_context->url_request_context_getter(); + browser_context->GetRequestContext(); context_getter->GetNetworkTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy, base::Unretained(this), context_getter, url)); @@ -453,15 +453,6 @@ void SetDevToolsNetworkEmulationClientIdInIO( network_delegate->SetDevToolsNetworkEmulationClientId(client_id); } -// Clear protocol handlers in IO thread. -void ClearJobFactoryInIO( - scoped_refptr request_context_getter) { - auto* job_factory = static_cast( - request_context_getter->job_factory()); - if (job_factory) - job_factory->Clear(); -} - void DestroyGlobalHandle(v8::Isolate* isolate, const v8::Global& global_handle) { v8::Locker locker(isolate); @@ -495,10 +486,6 @@ Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context) } Session::~Session() { - auto* getter = browser_context_->GetRequestContext(); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(ClearJobFactoryInIO, base::RetainedRef(getter))); content::BrowserContext::GetDownloadManager(browser_context()) ->RemoveObserver(this); DestroyGlobalHandle(isolate(), cookies_); @@ -597,10 +584,9 @@ void Session::EnableNetworkEmulation(const mate::Dictionary& options) { devtools_network_emulation_client_id_, std::move(conditions)); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::BindOnce( - &SetDevToolsNetworkEmulationClientIdInIO, - base::RetainedRef(browser_context_->url_request_context_getter()), - devtools_network_emulation_client_id_)); + base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO, + base::RetainedRef(browser_context_->GetRequestContext()), + devtools_network_emulation_client_id_)); } void Session::DisableNetworkEmulation() { @@ -609,10 +595,9 @@ void Session::DisableNetworkEmulation() { devtools_network_emulation_client_id_, std::move(conditions)); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::BindOnce( - &SetDevToolsNetworkEmulationClientIdInIO, - base::RetainedRef(browser_context_->url_request_context_getter()), - std::string())); + base::BindOnce(&SetDevToolsNetworkEmulationClientIdInIO, + base::RetainedRef(browser_context_->GetRequestContext()), + std::string())); } void Session::SetCertVerifyProc(v8::Local val, diff --git a/atom/browser/api/atom_api_web_request.cc b/atom/browser/api/atom_api_web_request.cc index ac265fb168ae..c088196f8331 100644 --- a/atom/browser/api/atom_api_web_request.cc +++ b/atom/browser/api/atom_api_web_request.cc @@ -95,7 +95,7 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) { } brightray::URLRequestContextGetter* url_request_context_getter = - browser_context_->url_request_context_getter(); + browser_context_->GetRequestContext(); if (!url_request_context_getter) return; BrowserThread::PostTask( diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index e3dbfedc0c2d..ffef00da50a6 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -4,59 +4,30 @@ #include "atom/browser/atom_browser_context.h" -#include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/atom_blob_reader.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/atom_download_manager_delegate.h" #include "atom/browser/atom_permission_manager.h" #include "atom/browser/browser.h" -#include "atom/browser/net/about_protocol_handler.h" -#include "atom/browser/net/asar/asar_protocol_handler.h" -#include "atom/browser/net/atom_cert_verifier.h" -#include "atom/browser/net/atom_network_delegate.h" -#include "atom/browser/net/atom_url_request_job_factory.h" -#include "atom/browser/net/cookie_details.h" -#include "atom/browser/net/http_protocol_handler.h" +#include "atom/browser/request_context_delegate.h" #include "atom/browser/web_view_manager.h" #include "atom/common/atom_version.h" #include "atom/common/chrome_version.h" #include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" -#include "base/memory/ptr_util.h" #include "base/path_service.h" -#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/task_scheduler/post_task.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_registry_simple.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/common/url_constants.h" #include "content/public/common/user_agent.h" -#include "net/ftp/ftp_network_layer.h" -#include "net/url_request/data_protocol_handler.h" -#include "net/url_request/ftp_protocol_handler.h" -#include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_intercepting_job_factory.h" -#include "url/url_constants.h" - -using content::BrowserThread; namespace atom { namespace { -class NoCacheBackend : public net::HttpCache::BackendFactory { - int CreateBackend(net::NetLog* net_log, - std::unique_ptr* backend, - const net::CompletionCallback& callback) override { - return net::ERR_FAILED; - } -}; - std::string RemoveWhitespace(const std::string& str) { std::string trimmed; if (base::RemoveChars(str, " ", &trimmed)) @@ -70,7 +41,8 @@ std::string RemoveWhitespace(const std::string& str) { AtomBrowserContext::AtomBrowserContext(const std::string& partition, bool in_memory, const base::DictionaryValue& options) - : brightray::BrowserContext(partition, in_memory) { + : brightray::BrowserContext(partition, in_memory), + url_request_context_getter_(nullptr) { // Construct user agent string. Browser* browser = Browser::Get(); std::string name = RemoveWhitespace(browser->GetName()); @@ -86,87 +58,24 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition, user_agent_ = content::BuildUserAgentFromProduct(user_agent); // Read options. - use_cache_ = true; - options.GetBoolean("cache", &use_cache_); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + bool use_cache = !command_line->HasSwitch(switches::kDisableHttpCache); + options.GetBoolean("cache", &use_cache); + + request_context_delegate_.reset(new RequestContextDelegate(use_cache)); // Initialize Pref Registry in brightray. InitPrefs(); } -AtomBrowserContext::~AtomBrowserContext() {} +AtomBrowserContext::~AtomBrowserContext() { + url_request_context_getter_->set_delegate(nullptr); +} void AtomBrowserContext::SetUserAgent(const std::string& user_agent) { user_agent_ = user_agent; } -std::unique_ptr::Subscription> -AtomBrowserContext::RegisterCookieChangeCallback( - const base::Callback& cb) { - return cookie_change_sub_list_.Add(cb); -} - -std::unique_ptr -AtomBrowserContext::CreateNetworkDelegate() { - return std::make_unique(); -} - -std::string AtomBrowserContext::GetUserAgent() { - return user_agent_; -} - -std::unique_ptr -AtomBrowserContext::CreateURLRequestJobFactory( - content::ProtocolHandlerMap* protocol_handlers) { - std::unique_ptr job_factory( - new AtomURLRequestJobFactory); - - for (auto& it : *protocol_handlers) { - job_factory->SetProtocolHandler(it.first, - base::WrapUnique(it.second.release())); - } - protocol_handlers->clear(); - - job_factory->SetProtocolHandler(url::kAboutScheme, - base::WrapUnique(new AboutProtocolHandler)); - job_factory->SetProtocolHandler( - url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler)); - job_factory->SetProtocolHandler( - url::kFileScheme, - base::WrapUnique( - new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})))); - job_factory->SetProtocolHandler( - url::kHttpScheme, - base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme))); - job_factory->SetProtocolHandler( - url::kHttpsScheme, - base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme))); - job_factory->SetProtocolHandler( - url::kWsScheme, - base::WrapUnique(new HttpProtocolHandler(url::kWsScheme))); - job_factory->SetProtocolHandler( - url::kWssScheme, - base::WrapUnique(new HttpProtocolHandler(url::kWssScheme))); - - auto* host_resolver = - url_request_context_getter()->GetURLRequestContext()->host_resolver(); - job_factory->SetProtocolHandler( - url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver)); - - return std::move(job_factory); -} - -net::HttpCache::BackendFactory* -AtomBrowserContext::CreateHttpCacheBackendFactory( - const base::FilePath& base_path) { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (!use_cache_ || command_line->HasSwitch(switches::kDisableHttpCache)) - return new NoCacheBackend; - else - return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path); -} - content::DownloadManagerDelegate* AtomBrowserContext::GetDownloadManagerDelegate() { if (!download_manager_delegate_.get()) { @@ -189,26 +98,6 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() { return permission_manager_.get(); } -std::unique_ptr AtomBrowserContext::CreateCertVerifier( - brightray::RequireCTDelegate* ct_delegate) { - return base::WrapUnique(new AtomCertVerifier(ct_delegate)); -} - -std::vector AtomBrowserContext::GetCookieableSchemes() { - auto default_schemes = brightray::BrowserContext::GetCookieableSchemes(); - const auto& standard_schemes = atom::api::GetStandardSchemes(); - default_schemes.insert(default_schemes.end(), standard_schemes.begin(), - standard_schemes.end()); - return default_schemes; -} - -void AtomBrowserContext::NotifyCookieChange(const net::CanonicalCookie& cookie, - bool removed, - net::CookieChangeCause cause) { - CookieDetails cookie_details(&cookie, removed, cause); - cookie_change_sub_list_.Notify(&cookie_details); -} - void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, base::FilePath()); @@ -219,6 +108,16 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); } +std::string AtomBrowserContext::GetUserAgent() const { + return user_agent_; +} + +void AtomBrowserContext::OnMainRequestContextCreated( + brightray::URLRequestContextGetter* getter) { + getter->set_delegate(request_context_delegate_.get()); + url_request_context_getter_ = getter; +} + AtomBlobReader* AtomBrowserContext::GetBlobReader() { if (!blob_reader_.get()) { content::ChromeBlobStorageContext* blob_context = diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index b60a4e682b0a..581ecc185f12 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -8,17 +8,15 @@ #include #include -#include "base/callback_list.h" #include "brightray/browser/browser_context.h" namespace atom { class AtomBlobReader; class AtomDownloadManagerDelegate; -class AtomNetworkDelegate; class AtomPermissionManager; +class RequestContextDelegate; class WebViewManager; -struct CookieDetails; class AtomBrowserContext : public brightray::BrowserContext { public: @@ -31,24 +29,7 @@ class AtomBrowserContext : public brightray::BrowserContext { const base::DictionaryValue& options = base::DictionaryValue()); void SetUserAgent(const std::string& user_agent); - // Register callbacks that needs to notified on any cookie store changes. - std::unique_ptr::Subscription> - RegisterCookieChangeCallback( - const base::Callback& cb); - - // brightray::URLRequestContextGetter::Delegate: - std::unique_ptr CreateNetworkDelegate() override; - std::string GetUserAgent() override; - std::unique_ptr CreateURLRequestJobFactory( - content::ProtocolHandlerMap* protocol_handlers) override; - net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory( - const base::FilePath& base_path) override; - std::unique_ptr CreateCertVerifier( - brightray::RequireCTDelegate* ct_delegate) override; - std::vector GetCookieableSchemes() override; - void NotifyCookieChange(const net::CanonicalCookie& cookie, - bool removed, - net::CookieChangeCause cause) override; + AtomBlobReader* GetBlobReader(); // content::BrowserContext: content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; @@ -57,14 +38,12 @@ class AtomBrowserContext : public brightray::BrowserContext { // brightray::BrowserContext: void RegisterPrefs(PrefRegistrySimple* pref_registry) override; + std::string GetUserAgent() const override; + void OnMainRequestContextCreated( + brightray::URLRequestContextGetter* getter) override; - AtomBlobReader* GetBlobReader(); - - void set_cookie_change_subscription( - std::unique_ptr< - base::CallbackList::Subscription> - subscription) { - cookie_change_subscription_.swap(subscription); + RequestContextDelegate* GetRequestContextDelegate() const { + return request_context_delegate_.get(); } protected: @@ -74,16 +53,14 @@ class AtomBrowserContext : public brightray::BrowserContext { ~AtomBrowserContext() override; private: + brightray::URLRequestContextGetter* url_request_context_getter_; + std::unique_ptr download_manager_delegate_; std::unique_ptr guest_manager_; std::unique_ptr permission_manager_; std::unique_ptr blob_reader_; + std::unique_ptr request_context_delegate_; std::string user_agent_; - bool use_cache_; - - base::CallbackList cookie_change_sub_list_; - std::unique_ptr::Subscription> - cookie_change_subscription_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext); }; diff --git a/atom/browser/net/atom_url_request.cc b/atom/browser/net/atom_url_request.cc index 8c0fbc4987bd..5ffbfd65a48b 100644 --- a/atom/browser/net/atom_url_request.cc +++ b/atom/browser/net/atom_url_request.cc @@ -70,11 +70,8 @@ scoped_refptr AtomURLRequest::Create( return nullptr; } scoped_refptr request_context_getter( - browser_context->url_request_context_getter()); + browser_context->GetRequestContext()); DCHECK(request_context_getter); - if (!request_context_getter) { - return nullptr; - } scoped_refptr atom_url_request(new AtomURLRequest(delegate)); if (content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index 09f7277ab659..68539433f4de 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -9,6 +9,7 @@ #include "atom/browser/api/atom_api_session.h" #include "atom/browser/atom_browser_context.h" +#include "base/guid.h" #include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "native_mate/dictionary.h" @@ -93,16 +94,15 @@ void URLRequestFetchJob::BeforeStartInUI(v8::Isolate* isolate, if (options.Get("session", &val)) { if (val->IsNull()) { // We have to create the URLRequestContextGetter on UI thread. - url_request_context_getter_ = new brightray::URLRequestContextGetter( - this, nullptr, base::FilePath(), true, - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), nullptr, - content::URLRequestInterceptorScopedVector()); + custom_browser_context_ = + AtomBrowserContext::From(base::GenerateGUID(), true); + url_request_context_getter_ = + custom_browser_context_->GetRequestContext(); } else { mate::Handle session; if (mate::ConvertFromV8(isolate, val, &session) && !session.IsEmpty()) { AtomBrowserContext* browser_context = session->browser_context(); - url_request_context_getter_ = - browser_context->url_request_context_getter(); + url_request_context_getter_ = browser_context->GetRequestContext(); } } } diff --git a/atom/browser/net/url_request_fetch_job.h b/atom/browser/net/url_request_fetch_job.h index d952074b2097..c38be1cbf86c 100644 --- a/atom/browser/net/url_request_fetch_job.h +++ b/atom/browser/net/url_request_fetch_job.h @@ -8,16 +8,17 @@ #include #include "atom/browser/net/js_asker.h" -#include "brightray/browser/url_request_context_getter.h" #include "content/browser/streams/stream.h" #include "content/browser/streams/stream_read_observer.h" #include "net/url_request/url_fetcher_delegate.h" +#include "net/url_request/url_request_context_getter.h" namespace atom { +class AtomBrowserContext; + class URLRequestFetchJob : public JsAsker, - public net::URLFetcherDelegate, - public brightray::URLRequestContextGetter::Delegate { + public net::URLFetcherDelegate { public: URLRequestFetchJob(net::URLRequest*, net::NetworkDelegate*); ~URLRequestFetchJob() override; @@ -51,6 +52,7 @@ class URLRequestFetchJob : public JsAsker, void ClearPendingBuffer(); void ClearWriteBuffer(); + scoped_refptr custom_browser_context_; scoped_refptr url_request_context_getter_; std::unique_ptr fetcher_; std::unique_ptr response_info_; diff --git a/atom/browser/request_context_delegate.cc b/atom/browser/request_context_delegate.cc new file mode 100644 index 000000000000..2bc44804878d --- /dev/null +++ b/atom/browser/request_context_delegate.cc @@ -0,0 +1,163 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/request_context_delegate.h" + +#include "atom/browser/api/atom_api_protocol.h" +#include "atom/browser/net/about_protocol_handler.h" +#include "atom/browser/net/asar/asar_protocol_handler.h" +#include "atom/browser/net/atom_cert_verifier.h" +#include "atom/browser/net/atom_network_delegate.h" +#include "atom/browser/net/atom_url_request_job_factory.h" +#include "atom/browser/net/cookie_details.h" +#include "atom/browser/net/http_protocol_handler.h" +#include "atom/common/options_switches.h" +#include "base/strings/string_number_conversions.h" +#include "base/task_scheduler/post_task.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/url_constants.h" +#include "net/ftp/ftp_network_layer.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/ftp_protocol_handler.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_intercepting_job_factory.h" +#include "url/url_constants.h" + +using content::BrowserThread; + +namespace atom { + +namespace { + +class NoCacheBackend : public net::HttpCache::BackendFactory { + int CreateBackend(net::NetLog* net_log, + std::unique_ptr* backend, + const net::CompletionCallback& callback) override { + return net::ERR_FAILED; + } +}; + +} // namespace + +RequestContextDelegate::RequestContextDelegate(bool use_cache) + : use_cache_(use_cache), weak_factory_(this) {} + +RequestContextDelegate::~RequestContextDelegate() {} + +std::unique_ptr::Subscription> +RequestContextDelegate::RegisterCookieChangeCallback( + const base::Callback& cb) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + return cookie_change_sub_list_.Add(cb); +} + +void RequestContextDelegate::NotifyCookieChange( + const net::CanonicalCookie& cookie, + net::CookieChangeCause cause) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + CookieDetails cookie_details( + &cookie, !(cause == net::CookieChangeCause::INSERTED), cause); + cookie_change_sub_list_.Notify(&cookie_details); +} + +std::unique_ptr +RequestContextDelegate::CreateNetworkDelegate() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + return std::make_unique(); +} + +std::unique_ptr +RequestContextDelegate::CreateURLRequestJobFactory( + net::URLRequestContext* url_request_context, + content::ProtocolHandlerMap* protocol_handlers) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + std::unique_ptr job_factory( + new AtomURLRequestJobFactory); + + for (auto& it : *protocol_handlers) { + job_factory->SetProtocolHandler(it.first, + base::WrapUnique(it.second.release())); + } + protocol_handlers->clear(); + + job_factory->SetProtocolHandler(url::kAboutScheme, + base::WrapUnique(new AboutProtocolHandler)); + job_factory->SetProtocolHandler( + url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler)); + job_factory->SetProtocolHandler( + url::kFileScheme, + base::WrapUnique( + new asar::AsarProtocolHandler(base::CreateTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})))); + job_factory->SetProtocolHandler( + url::kHttpScheme, + base::WrapUnique(new HttpProtocolHandler(url::kHttpScheme))); + job_factory->SetProtocolHandler( + url::kHttpsScheme, + base::WrapUnique(new HttpProtocolHandler(url::kHttpsScheme))); + job_factory->SetProtocolHandler( + url::kWsScheme, + base::WrapUnique(new HttpProtocolHandler(url::kWsScheme))); + job_factory->SetProtocolHandler( + url::kWssScheme, + base::WrapUnique(new HttpProtocolHandler(url::kWssScheme))); + + auto* host_resolver = url_request_context->host_resolver(); + job_factory->SetProtocolHandler( + url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver)); + + return std::move(job_factory); +} + +net::HttpCache::BackendFactory* +RequestContextDelegate::CreateHttpCacheBackendFactory( + const base::FilePath& base_path) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!use_cache_) { + return new NoCacheBackend; + } else { + int max_size = 0; + base::StringToInt( + command_line->GetSwitchValueASCII(switches::kDiskCacheSize), &max_size); + + base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache")); + return new net::HttpCache::DefaultBackend( + net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size); + } +} + +std::unique_ptr RequestContextDelegate::CreateCertVerifier( + brightray::RequireCTDelegate* ct_delegate) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + return std::make_unique(ct_delegate); +} + +void RequestContextDelegate::GetCookieableSchemes( + std::vector* cookie_schemes) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + const auto& standard_schemes = atom::api::GetStandardSchemes(); + cookie_schemes->insert(cookie_schemes->end(), standard_schemes.begin(), + standard_schemes.end()); +} + +void RequestContextDelegate::OnCookieChanged(const net::CanonicalCookie& cookie, + net::CookieChangeCause cause) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::BindRepeating(&RequestContextDelegate::NotifyCookieChange, + weak_factory_.GetWeakPtr(), cookie, cause)); +} + +} // namespace atom diff --git a/atom/browser/request_context_delegate.h b/atom/browser/request_context_delegate.h new file mode 100644 index 000000000000..7a6200a439f7 --- /dev/null +++ b/atom/browser/request_context_delegate.h @@ -0,0 +1,58 @@ +// Copyright (c) 2018 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_ +#define ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_ + +#include +#include + +#include "base/callback_list.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "brightray/browser/url_request_context_getter.h" + +namespace atom { + +struct CookieDetails; + +class RequestContextDelegate + : public brightray::URLRequestContextGetter::Delegate { + public: + explicit RequestContextDelegate(bool use_cache); + ~RequestContextDelegate() override; + + // Register callbacks that needs to notified on any cookie store changes. + std::unique_ptr::Subscription> + RegisterCookieChangeCallback( + const base::Callback& cb); + + protected: + std::unique_ptr CreateNetworkDelegate() override; + std::unique_ptr CreateURLRequestJobFactory( + net::URLRequestContext* url_request_context, + content::ProtocolHandlerMap* protocol_handlers) override; + net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory( + const base::FilePath& base_path) override; + std::unique_ptr CreateCertVerifier( + brightray::RequireCTDelegate* ct_delegate) override; + void GetCookieableSchemes(std::vector* cookie_schemes) override; + void OnCookieChanged(const net::CanonicalCookie& cookie, + net::CookieChangeCause cause) override; + + private: + void NotifyCookieChange(const net::CanonicalCookie& cookie, + net::CookieChangeCause cause); + + base::CallbackList cookie_change_sub_list_; + bool use_cache_ = true; + + base::WeakPtrFactory weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(RequestContextDelegate); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_REQUEST_CONTEXT_DELEGATE_H_ diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 17a8800d24f5..1e878a1153d2 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -210,6 +210,9 @@ const char kWidevineCdmPath[] = "widevine-cdm-path"; // Widevine CDM version. const char kWidevineCdmVersion[] = "widevine-cdm-version"; +// Forces the maximum disk space to be used by the disk cache, in bytes. +const char kDiskCacheSize[] = "disk-cache-size"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 387b11d8d657..83c0d7692a7e 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -109,6 +109,8 @@ extern const char kWebviewTag[]; extern const char kWidevineCdmPath[]; extern const char kWidevineCdmVersion[]; +extern const char kDiskCacheSize[]; + } // namespace switches } // namespace atom diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc index 6123937cb564..708a97bddd1e 100644 --- a/brightray/browser/browser_context.cc +++ b/brightray/browser/browser_context.cc @@ -11,7 +11,6 @@ #include "brightray/browser/brightray_paths.h" #include "brightray/browser/browser_client.h" #include "brightray/browser/inspectable_web_contents_impl.h" -#include "brightray/browser/network_delegate.h" #include "brightray/browser/special_storage_policy.h" #include "brightray/browser/zoom_level_delegate.h" #include "brightray/common/application_info.h" @@ -20,7 +19,6 @@ #include "components/prefs/pref_service.h" #include "components/prefs/pref_service_factory.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/resource_context.h" #include "content/public/browser/storage_partition.h" #include "net/base/escape.h" @@ -37,25 +35,10 @@ std::string MakePartitionName(const std::string& input) { } // namespace -class BrowserContext::ResourceContext : public content::ResourceContext { - public: - ResourceContext() : getter_(nullptr) {} - - void set_url_request_context_getter(URLRequestContextGetter* getter) { - getter_ = getter; - } - - private: - net::HostResolver* GetHostResolver() override { - return getter_->host_resolver(); - } - - net::URLRequestContext* GetRequestContext() override { - return getter_->GetURLRequestContext(); - } - - URLRequestContextGetter* getter_; -}; +// static +void BrowserContextDeleter::Destruct(const BrowserContext* browser_context) { + browser_context->OnDestruct(); +} // static BrowserContext::BrowserContextMap BrowserContext::browser_context_map_; @@ -72,7 +55,6 @@ scoped_refptr BrowserContext::Get(const std::string& partition, BrowserContext::BrowserContext(const std::string& partition, bool in_memory) : in_memory_(in_memory), - resource_context_(new ResourceContext), storage_policy_(new SpecialStoragePolicy), weak_factory_(this) { if (!PathService::Get(DIR_USER_DATA, &path_)) { @@ -88,6 +70,8 @@ BrowserContext::BrowserContext(const std::string& partition, bool in_memory) content::BrowserContext::Initialize(this, path_); + io_handle_ = new URLRequestContextGetter::Handle(GetWeakPtr()); + browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr(); } @@ -95,13 +79,14 @@ BrowserContext::~BrowserContext() { DCHECK_CURRENTLY_ON(BrowserThread::UI); NotifyWillBeDestroyed(this); ShutdownStoragePartitions(); - if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { - BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, - resource_context_.release()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&URLRequestContextGetter::NotifyContextShutdownOnIO, - base::RetainedRef(url_request_getter_))); + io_handle_->ShutdownOnUIThread(); +} + +void BrowserContext::OnDestruct() const { + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { + delete this; + } else { + BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); } } @@ -135,17 +120,10 @@ URLRequestContextGetter* BrowserContext::GetRequestContext() { net::URLRequestContextGetter* BrowserContext::CreateRequestContext( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector protocol_interceptors) { - DCHECK(!url_request_getter_.get()); - url_request_getter_ = new URLRequestContextGetter( - this, static_cast(BrowserClient::Get()->GetNetLog()), GetPath(), - in_memory_, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), - protocol_handlers, std::move(protocol_interceptors)); - resource_context_->set_url_request_context_getter(url_request_getter_.get()); - return url_request_getter_.get(); -} - -std::unique_ptr BrowserContext::CreateNetworkDelegate() { - return std::make_unique(); + return io_handle_ + ->CreateMainRequestContextGetter(protocol_handlers, + std::move(protocol_interceptors)) + .get(); } std::string BrowserContext::GetMediaDeviceIDSalt() { @@ -171,7 +149,7 @@ bool BrowserContext::IsOffTheRecord() const { } content::ResourceContext* BrowserContext::GetResourceContext() { - return resource_context_.get(); + return io_handle_->GetResourceContext(); } content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() { @@ -214,17 +192,19 @@ BrowserContext::CreateRequestContextForStoragePartition( bool in_memory, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) { + NOTREACHED(); return nullptr; } net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() { - return url_request_getter_.get(); + return io_handle_->GetMainRequestContextGetter().get(); } net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContextForStoragePartition( const base::FilePath& partition_path, bool in_memory) { + NOTREACHED(); return nullptr; } diff --git a/brightray/browser/browser_context.h b/brightray/browser/browser_context.h index 8f3de784cfe2..d36ec3bbdff9 100644 --- a/brightray/browser/browser_context.h +++ b/brightray/browser/browser_context.h @@ -23,9 +23,15 @@ class SpecialStoragePolicy; namespace brightray { -class BrowserContext : public base::RefCounted, - public content::BrowserContext, - public brightray::URLRequestContextGetter::Delegate { +class BrowserContext; + +struct BrowserContextDeleter { + static void Destruct(const BrowserContext* browser_context); +}; + +class BrowserContext + : public base::RefCountedThreadSafe, + public content::BrowserContext { public: // Get the BrowserContext according to its |partition| and |in_memory|, // empty pointer when be returned when there is no matching BrowserContext. @@ -66,14 +72,14 @@ class BrowserContext : public base::RefCounted, const base::FilePath& partition_path, bool in_memory) override; std::string GetMediaDeviceIDSalt() override; - - URLRequestContextGetter* url_request_context_getter() const { - return url_request_getter_.get(); - } + base::FilePath GetPath() const override; void InitPrefs(); PrefService* prefs() { return prefs_.get(); } + virtual std::string GetUserAgent() const = 0; + virtual void OnMainRequestContextCreated(URLRequestContextGetter* getter) {} + protected: BrowserContext(const std::string& partition, bool in_memory); ~BrowserContext() override; @@ -81,16 +87,14 @@ class BrowserContext : public base::RefCounted, // Subclasses should override this to register custom preferences. virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {} - // URLRequestContextGetter::Delegate: - std::unique_ptr CreateNetworkDelegate() override; - - base::FilePath GetPath() const override; - private: - friend class base::RefCounted; - class ResourceContext; + friend class base::RefCountedThreadSafe; + friend class base::DeleteHelper; + friend struct BrowserContextDeleter; void RegisterInternalPrefs(PrefRegistrySimple* pref_registry); + void OnDestruct() const; // partition_id => browser_context struct PartitionKey { @@ -117,11 +121,12 @@ class BrowserContext : public base::RefCounted, base::FilePath path_; bool in_memory_; - std::unique_ptr resource_context_; - scoped_refptr url_request_getter_; scoped_refptr storage_policy_; std::unique_ptr prefs_; std::unique_ptr media_device_id_salt_; + // Self-destructing class responsible for creating URLRequestContextGetter + // on the UI thread and deletes itself on the IO thread. + URLRequestContextGetter::Handle* io_handle_; base::WeakPtrFactory weak_factory_; diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 426df497c60b..6784180a7f6b 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -472,7 +472,7 @@ void InspectableWebContentsImpl::LoadNetworkResource( net::URLFetcher* fetcher = (net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release(); pending_requests_[fetcher] = callback; - fetcher->SetRequestContext(browser_context->url_request_context_getter()); + fetcher->SetRequestContext(browser_context->GetRequestContext()); fetcher->SetExtraRequestHeaders(headers); fetcher->SaveResponseWithWriter( std::unique_ptr( diff --git a/brightray/browser/url_request_context_getter.cc b/brightray/browser/url_request_context_getter.cc index 68041972af79..6bad48ee517b 100644 --- a/brightray/browser/url_request_context_getter.cc +++ b/brightray/browser/url_request_context_getter.cc @@ -12,6 +12,7 @@ #include "base/strings/string_util.h" #include "base/task_scheduler/post_task.h" #include "brightray/browser/browser_client.h" +#include "brightray/browser/browser_context.h" #include "brightray/browser/net/require_ct_delegate.h" #include "brightray/browser/net_log.h" #include "brightray/browser/network_delegate.h" @@ -20,6 +21,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/cookie_store_factory.h" #include "content/public/browser/devtools_network_transaction_factory.h" +#include "content/public/browser/resource_context.h" #include "net/base/host_mapping_rules.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_known_logs.h" @@ -58,83 +60,107 @@ using content::BrowserThread; namespace brightray { -std::string URLRequestContextGetter::Delegate::GetUserAgent() { - return base::EmptyString(); -} +class ResourceContext : public content::ResourceContext { + public: + ResourceContext() = default; + ~ResourceContext() override = default; -std::unique_ptr -URLRequestContextGetter::Delegate::CreateNetworkDelegate() { - return nullptr; -} - -std::unique_ptr -URLRequestContextGetter::Delegate::CreateURLRequestJobFactory( - content::ProtocolHandlerMap* protocol_handlers) { - std::unique_ptr job_factory( - new net::URLRequestJobFactoryImpl); - - for (auto& it : *protocol_handlers) { - job_factory->SetProtocolHandler(it.first, - base::WrapUnique(it.second.release())); + net::HostResolver* GetHostResolver() override { + if (request_context_) + return request_context_->host_resolver(); + return nullptr; } - protocol_handlers->clear(); - job_factory->SetProtocolHandler( - url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler)); - job_factory->SetProtocolHandler( - url::kFileScheme, - base::WrapUnique( - new net::FileProtocolHandler(base::CreateTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE, - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})))); + net::URLRequestContext* GetRequestContext() override { + return request_context_; + } - return std::move(job_factory); + private: + friend class URLRequestContextGetter; + + net::URLRequestContext* request_context_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(ResourceContext); +}; + +URLRequestContextGetter::Handle::Handle( + base::WeakPtr browser_context) + : resource_context_(new ResourceContext), + browser_context_(browser_context), + initialized_(false) {} + +URLRequestContextGetter::Handle::~Handle() {} + +content::ResourceContext* URLRequestContextGetter::Handle::GetResourceContext() + const { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + LazyInitialize(); + return resource_context_.get(); } -net::HttpCache::BackendFactory* -URLRequestContextGetter::Delegate::CreateHttpCacheBackendFactory( - const base::FilePath& base_path) { - auto* command_line = base::CommandLine::ForCurrentProcess(); - int max_size = 0; - base::StringToInt(command_line->GetSwitchValueASCII(switches::kDiskCacheSize), - &max_size); - - base::FilePath cache_path = base_path.Append(FILE_PATH_LITERAL("Cache")); - return new net::HttpCache::DefaultBackend( - net::DISK_CACHE, net::CACHE_BACKEND_DEFAULT, cache_path, max_size); +scoped_refptr +URLRequestContextGetter::Handle::CreateMainRequestContextGetter( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector protocol_interceptors) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!main_request_context_getter_.get()); + main_request_context_getter_ = new URLRequestContextGetter( + BrowserClient::Get()->GetNetLog(), resource_context_.get(), + browser_context_->IsOffTheRecord(), browser_context_->GetUserAgent(), + browser_context_->GetPath(), protocol_handlers, + std::move(protocol_interceptors)); + browser_context_->OnMainRequestContextCreated( + main_request_context_getter_.get()); + return main_request_context_getter_; } -std::unique_ptr -URLRequestContextGetter::Delegate::CreateCertVerifier( - RequireCTDelegate* ct_delegate) { - return net::CertVerifier::CreateDefault(); +scoped_refptr +URLRequestContextGetter::Handle::GetMainRequestContextGetter() const { + return main_request_context_getter_; } -net::SSLConfigService* -URLRequestContextGetter::Delegate::CreateSSLConfigService() { - return new net::SSLConfigServiceDefaults; +void URLRequestContextGetter::Handle::LazyInitialize() const { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (initialized_) + return; + + initialized_ = true; + content::BrowserContext::EnsureResourceContextInitialized( + browser_context_.get()); } -std::vector -URLRequestContextGetter::Delegate::GetCookieableSchemes() { - return {"http", "https", "ws", "wss"}; +void URLRequestContextGetter::Handle::ShutdownOnUIThread() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (main_request_context_getter_.get()) { + if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&URLRequestContextGetter::NotifyContextShuttingDown, + base::RetainedRef(main_request_context_getter_), + std::move(resource_context_))); + } + } + + if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this)) + delete this; } URLRequestContextGetter::URLRequestContextGetter( - Delegate* delegate, NetLog* net_log, - const base::FilePath& base_path, + ResourceContext* resource_context, bool in_memory, - scoped_refptr io_task_runner, + const std::string& user_agent, + const base::FilePath& base_path, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector protocol_interceptors) - : delegate_(delegate), + : job_factory_(nullptr), + delegate_(nullptr), net_log_(net_log), + resource_context_(resource_context), + protocol_interceptors_(std::move(protocol_interceptors)), base_path_(base_path), in_memory_(in_memory), - io_task_runner_(io_task_runner), - protocol_interceptors_(std::move(protocol_interceptors)), - job_factory_(nullptr), + user_agent_(user_agent), context_shutting_down_(false) { // Must first be created on the UI thread. DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -142,48 +168,30 @@ URLRequestContextGetter::URLRequestContextGetter( if (protocol_handlers) std::swap(protocol_handlers_, *protocol_handlers); - if (delegate_) - user_agent_ = delegate_->GetUserAgent(); - // We must create the proxy config service on the UI loop on Linux because it // must synchronously run on the glib message loop. This will be passed to // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). proxy_config_service_ = net::ProxyResolutionService::CreateSystemProxyConfigService( - io_task_runner_); + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); } URLRequestContextGetter::~URLRequestContextGetter() {} -void URLRequestContextGetter::NotifyContextShutdownOnIO() { +void URLRequestContextGetter::NotifyContextShuttingDown( + std::unique_ptr resource_context) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + context_shutting_down_ = true; cookie_change_sub_.reset(); + resource_context.reset(); + net::URLRequestContextGetter::NotifyContextShuttingDown(); + url_request_context_.reset(); + storage_.reset(); http_network_session_.reset(); http_auth_preferences_.reset(); host_mapping_rules_.reset(); - url_request_context_.reset(); - storage_.reset(); ct_delegate_.reset(); - net::URLRequestContextGetter::NotifyContextShuttingDown(); -} - -void URLRequestContextGetter::OnCookieChanged( - const net::CanonicalCookie& cookie, - net::CookieChangeCause cause) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - if (!delegate_ || context_shutting_down_) - return; - - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce(&Delegate::NotifyCookieChange, base::Unretained(delegate_), - cookie, !(cause == net::CookieChangeCause::INSERTED), - cause)); -} - -net::HostResolver* URLRequestContextGetter::host_resolver() { - return url_request_context_->host_resolver(); } net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { @@ -211,22 +219,23 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { auto cookie_path = in_memory_ ? base::FilePath() : base_path_.Append(FILE_PATH_LITERAL("Cookies")); - std::unique_ptr cookie_store = - content::CreateCookieStore(content::CookieStoreConfig( - cookie_path, false, false, nullptr)); + std::unique_ptr cookie_store = content::CreateCookieStore( + content::CookieStoreConfig(cookie_path, false, false, nullptr)); storage_->set_cookie_store(std::move(cookie_store)); // Set custom schemes that can accept cookies. net::CookieMonster* cookie_monster = static_cast(url_request_context_->cookie_store()); - cookie_monster->SetCookieableSchemes(delegate_->GetCookieableSchemes()); + std::vector cookie_schemes({"http", "https", "ws", "wss"}); + delegate_->GetCookieableSchemes(&cookie_schemes); + cookie_monster->SetCookieableSchemes(cookie_schemes); // Cookie store will outlive notifier by order of declaration // in the header. - cookie_change_sub_ = - url_request_context_->cookie_store() - ->GetChangeDispatcher() - .AddCallbackForAllChanges( - base::Bind(&URLRequestContextGetter::OnCookieChanged, this)); + cookie_change_sub_ = url_request_context_->cookie_store() + ->GetChangeDispatcher() + .AddCallbackForAllChanges(base::Bind( + &URLRequestContextGetter::OnCookieChanged, + base::RetainedRef(this))); storage_->set_channel_id_service(std::make_unique( new net::DefaultChannelIDStore(nullptr))); @@ -307,7 +316,7 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { storage_->set_transport_security_state(std::move(transport_security_state)); storage_->set_cert_verifier( delegate_->CreateCertVerifier(ct_delegate_.get())); - storage_->set_ssl_config_service(delegate_->CreateSSLConfigService()); + storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults()); storage_->set_http_auth_handler_factory(std::move(auth_handler_factory)); std::unique_ptr server_properties( new net::HttpServerPropertiesImpl); @@ -360,7 +369,8 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { std::move(backend), false)); std::unique_ptr job_factory = - delegate_->CreateURLRequestJobFactory(&protocol_handlers_); + delegate_->CreateURLRequestJobFactory(url_request_context_.get(), + &protocol_handlers_); job_factory_ = job_factory.get(); // Set up interceptors in the reverse order. @@ -378,6 +388,9 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { storage_->set_job_factory(std::move(top_job_factory)); } + if (resource_context_) + resource_context_->request_context_ = url_request_context_.get(); + return url_request_context_.get(); } @@ -386,4 +399,11 @@ URLRequestContextGetter::GetNetworkTaskRunner() const { return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO); } +void URLRequestContextGetter::OnCookieChanged( + const net::CanonicalCookie& cookie, + net::CookieChangeCause cause) const { + if (delegate_) + delegate_->OnCookieChanged(cookie, cause); +} + } // namespace brightray diff --git a/brightray/browser/url_request_context_getter.h b/brightray/browser/url_request_context_getter.h index b990d479a06c..941a5782b14a 100644 --- a/brightray/browser/url_request_context_getter.h +++ b/brightray/browser/url_request_context_getter.h @@ -22,10 +22,6 @@ #include "base/debug/leak_tracker.h" #endif -namespace base { -class MessageLoop; -} - namespace net { class HostMappingRules; class HostResolver; @@ -38,6 +34,8 @@ class URLRequestJobFactory; namespace brightray { +class BrowserContext; +class ResourceContext; class RequireCTDelegate; class NetLog; @@ -48,55 +46,76 @@ class URLRequestContextGetter : public net::URLRequestContextGetter { Delegate() {} virtual ~Delegate() {} - virtual std::unique_ptr CreateNetworkDelegate(); - virtual std::string GetUserAgent(); + virtual std::unique_ptr CreateNetworkDelegate() = 0; virtual std::unique_ptr - CreateURLRequestJobFactory(content::ProtocolHandlerMap* protocol_handlers); + CreateURLRequestJobFactory( + net::URLRequestContext* url_request_context, + content::ProtocolHandlerMap* protocol_handlers) = 0; virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory( - const base::FilePath& base_path); + const base::FilePath& base_path) = 0; virtual std::unique_ptr CreateCertVerifier( - RequireCTDelegate* ct_delegate); - virtual net::SSLConfigService* CreateSSLConfigService(); - virtual std::vector GetCookieableSchemes(); - virtual void NotifyCookieChange(const net::CanonicalCookie& cookie, - bool removed, - net::CookieChangeCause cause) {} + RequireCTDelegate* ct_delegate) = 0; + virtual void GetCookieableSchemes( + std::vector* cookie_schemes) {} + virtual void OnCookieChanged(const net::CanonicalCookie& cookie, + net::CookieChangeCause cause) {} }; URLRequestContextGetter( - Delegate* delegate, NetLog* net_log, - const base::FilePath& base_path, + ResourceContext* resource_context, bool in_memory, - scoped_refptr io_task_runner, + const std::string& user_agent, + const base::FilePath& base_path, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector protocol_interceptors); - // net::CookieChangeDispatcher::CookieChangedCallback implementation. - void OnCookieChanged(const net::CanonicalCookie& cookie, - net::CookieChangeCause cause); - // net::URLRequestContextGetter: net::URLRequestContext* GetURLRequestContext() override; scoped_refptr GetNetworkTaskRunner() const override; - net::HostResolver* host_resolver(); net::URLRequestJobFactory* job_factory() const { return job_factory_; } + void set_delegate(Delegate* delegate) { delegate_ = delegate; } - void NotifyContextShutdownOnIO(); + // Discard reference to URLRequestContext and inform observers to + // shutdown. Must be called only on IO thread. + void NotifyContextShuttingDown(std::unique_ptr); private: + friend class BrowserContext; + + // Responsible for destroying URLRequestContextGetter + // on the IO thread. + class Handle { + public: + explicit Handle(base::WeakPtr browser_context); + ~Handle(); + + scoped_refptr CreateMainRequestContextGetter( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector protocol_interceptors); + content::ResourceContext* GetResourceContext() const; + scoped_refptr GetMainRequestContextGetter() const; + + void ShutdownOnUIThread(); + + private: + void LazyInitialize() const; + + scoped_refptr main_request_context_getter_; + std::unique_ptr resource_context_; + base::WeakPtr browser_context_; + mutable bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(Handle); + }; + ~URLRequestContextGetter() override; - Delegate* delegate_; - - NetLog* net_log_; - base::FilePath base_path_; - bool in_memory_; - scoped_refptr io_task_runner_; - - std::string user_agent_; + // net::CookieChangeDispatcher::CookieChangedCallback implementation. + void OnCookieChanged(const net::CanonicalCookie& cookie, + net::CookieChangeCause cause) const; #if DCHECK_IS_ON() base::debug::LeakTracker leak_tracker_; @@ -110,11 +129,16 @@ class URLRequestContextGetter : public net::URLRequestContextGetter { std::unique_ptr http_auth_preferences_; std::unique_ptr http_network_session_; std::unique_ptr cookie_change_sub_; + + net::URLRequestJobFactory* job_factory_; + Delegate* delegate_; + NetLog* net_log_; + ResourceContext* resource_context_; content::ProtocolHandlerMap protocol_handlers_; content::URLRequestInterceptorScopedVector protocol_interceptors_; - - net::URLRequestJobFactory* job_factory_; // weak ref - + base::FilePath base_path_; + bool in_memory_; + std::string user_agent_; bool context_shutting_down_; DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); diff --git a/brightray/common/switches.cc b/brightray/common/switches.cc index 9985f9f15e0b..ef7a138375bd 100644 --- a/brightray/common/switches.cc +++ b/brightray/common/switches.cc @@ -50,9 +50,6 @@ const char kAuthServerWhitelist[] = "auth-server-whitelist"; const char kAuthNegotiateDelegateWhitelist[] = "auth-negotiate-delegate-whitelist"; -// Forces the maximum disk space to be used by the disk cache, in bytes. -const char kDiskCacheSize[] = "disk-cache-size"; - } // namespace switches } // namespace brightray diff --git a/brightray/common/switches.h b/brightray/common/switches.h index 6262f5f962ca..3af00813830f 100644 --- a/brightray/common/switches.h +++ b/brightray/common/switches.h @@ -17,7 +17,6 @@ extern const char kProxyPacUrl[]; extern const char kDisableHttp2[]; extern const char kAuthServerWhitelist[]; extern const char kAuthNegotiateDelegateWhitelist[]; -extern const char kDiskCacheSize[]; } // namespace switches diff --git a/filenames.gypi b/filenames.gypi index 2215cb4f6d89..31fb96254ecf 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -313,6 +313,8 @@ 'atom/browser/relauncher.h', 'atom/browser/render_process_preferences.cc', 'atom/browser/render_process_preferences.h', + 'atom/browser/request_context_delegate.cc', + 'atom/browser/request_context_delegate.h', 'atom/browser/session_preferences.cc', 'atom/browser/session_preferences.h', 'atom/browser/ui/accelerator_util.cc',