[WIP] refactor: (Part I) make the ownership of URLRequestContextGetter more clear (#13956)

* refactor: desttroy URLRequestContextGetter on IO thread

* Accepts a factory class that can customize the creation of URLRequestContext
* Use a separate request context for media which is derived from the default
* Notify URLRequestContextGetter observers and cleanup on IO thread
* Move most of brightray net/ classes into atom net/

* refactor: remove refs to URLRequestContextGetter on shutdown

* refactor: remove brigtray switches.{cc|h}

* refactor: remove brightray network_delegate.{cc|h}

* refactor: make AtomURLRequestJobFactory the top level factory.

* Allows to use the default handler from content/ for http{s}, ws{s} schemes.
* Removes the storage of job factory in URLRequestContextGetter.
This commit is contained in:
Robo 2018-08-14 03:52:45 +05:30 committed by Samuel Attard
parent cb4b3e7be0
commit 1c0bb06d4a
34 changed files with 985 additions and 1121 deletions

View file

@ -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,26 +35,6 @@ 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
BrowserContext::BrowserContextMap BrowserContext::browser_context_map_;
@ -72,7 +50,6 @@ scoped_refptr<BrowserContext> 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 +65,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,14 +74,7 @@ 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::InitPrefs() {
@ -135,17 +107,9 @@ 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<NetLog*>(BrowserClient::Get()->GetNetLog()), GetPath(),
in_memory_, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
auto* factory = GetFactoryForMainRequestContext(
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<net::NetworkDelegate> BrowserContext::CreateNetworkDelegate() {
return std::make_unique<NetworkDelegate>();
return io_handle_->CreateMainRequestContextGetter(factory).get();
}
std::string BrowserContext::GetMediaDeviceIDSalt() {
@ -171,7 +135,7 @@ bool BrowserContext::IsOffTheRecord() const {
}
content::ResourceContext* BrowserContext::GetResourceContext() {
return resource_context_.get();
return io_handle_->GetResourceContext();
}
content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() {
@ -214,17 +178,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_->GetMediaRequestContextGetter().get();
}
net::URLRequestContextGetter*
BrowserContext::CreateMediaRequestContextForStoragePartition(
const base::FilePath& partition_path,
bool in_memory) {
NOTREACHED();
return nullptr;
}

View file

@ -24,8 +24,7 @@ class SpecialStoragePolicy;
namespace brightray {
class BrowserContext : public base::RefCounted<BrowserContext>,
public content::BrowserContext,
public brightray::URLRequestContextGetter::Delegate {
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.
@ -67,10 +66,6 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
bool in_memory) override;
std::string GetMediaDeviceIDSalt() override;
URLRequestContextGetter* url_request_context_getter() const {
return url_request_getter_.get();
}
void InitPrefs();
PrefService* prefs() { return prefs_.get(); }
@ -80,15 +75,14 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
// Subclasses should override this to register custom preferences.
virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {}
// URLRequestContextGetter::Delegate:
std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate() override;
virtual URLRequestContextGetterFactory* GetFactoryForMainRequestContext(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) = 0;
base::FilePath GetPath() const override;
private:
friend class base::RefCounted<BrowserContext>;
class ResourceContext;
void RegisterInternalPrefs(PrefRegistrySimple* pref_registry);
@ -117,11 +111,10 @@ class BrowserContext : public base::RefCounted<BrowserContext>,
base::FilePath path_;
bool in_memory_;
std::unique_ptr<ResourceContext> resource_context_;
scoped_refptr<URLRequestContextGetter> url_request_getter_;
scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
std::unique_ptr<PrefService> prefs_;
std::unique_ptr<MediaDeviceIDSalt> media_device_id_salt_;
URLRequestContextGetter::Handle* io_handle_;
base::WeakPtrFactory<BrowserContext> weak_factory_;

View file

@ -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<net::URLFetcherResponseWriter>(

View file

@ -0,0 +1,29 @@
// 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 BRIGHTRAY_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_FACTORY_H_
#define BRIGHTRAY_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_FACTORY_H_
#include "base/macros.h"
namespace net {
class URLRequestContext;
} // namespace net
namespace brightray {
class URLRequestContextGetterFactory {
public:
URLRequestContextGetterFactory() {}
virtual ~URLRequestContextGetterFactory() {}
virtual net::URLRequestContext* Create() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetterFactory);
};
} // namespace brightray
#endif // BRIGHTRAY_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_FACTORY_H_

View file

@ -1,161 +0,0 @@
// Copyright (c) 2012 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-CHROMIUM file.
#include "brightray/browser/network_delegate.h"
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/strings/string_split.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
namespace brightray {
namespace {
// Ignore the limit of 6 connections per host.
const char kIgnoreConnectionsLimit[] = "ignore-connections-limit";
} // namespace
NetworkDelegate::NetworkDelegate() {
auto* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kIgnoreConnectionsLimit)) {
std::string value =
command_line->GetSwitchValueASCII(kIgnoreConnectionsLimit);
ignore_connections_limit_domains_ = base::SplitString(
value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
}
}
NetworkDelegate::~NetworkDelegate() {}
int NetworkDelegate::OnBeforeURLRequest(net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) {
for (const auto& domain : ignore_connections_limit_domains_) {
if (request->url().DomainIs(domain)) {
// Allow unlimited concurrent connections.
request->SetPriority(net::MAXIMUM_PRIORITY);
request->SetLoadFlags(request->load_flags() | net::LOAD_IGNORE_LIMITS);
break;
}
}
return net::OK;
}
int NetworkDelegate::OnBeforeStartTransaction(
net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) {
return net::OK;
}
void NetworkDelegate::OnStartTransaction(
net::URLRequest* request,
const net::HttpRequestHeaders& headers) {}
void NetworkDelegate::OnBeforeSendHeaders(
net::URLRequest* request,
const net::ProxyInfo& proxy_info,
const net::ProxyRetryInfoMap& proxy_retry_info,
net::HttpRequestHeaders* headers) {}
int NetworkDelegate::OnHeadersReceived(
net::URLRequest* request,
const net::CompletionCallback& callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) {
return net::OK;
}
void NetworkDelegate::OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) {}
void NetworkDelegate::OnResponseStarted(net::URLRequest* request,
int net_error) {}
void NetworkDelegate::OnNetworkBytesReceived(net::URLRequest* request,
int64_t bytes_read) {}
void NetworkDelegate::OnNetworkBytesSent(net::URLRequest* request,
int64_t bytes_sent) {}
void NetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {}
void NetworkDelegate::OnURLRequestDestroyed(net::URLRequest* request) {}
void NetworkDelegate::OnPACScriptError(int line_number,
const base::string16& error) {}
NetworkDelegate::AuthRequiredResponse NetworkDelegate::OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) {
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
}
bool NetworkDelegate::OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) {
return true;
}
bool NetworkDelegate::OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie_line,
net::CookieOptions* options) {
return true;
}
bool NetworkDelegate::OnCanAccessFile(
const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const {
return true;
}
bool NetworkDelegate::OnCanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const {
return false;
}
bool NetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
return true;
}
bool NetworkDelegate::OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const net::URLRequest& request,
const GURL& target_url,
const GURL& referrer_url) const {
return false;
}
// TODO(deepak1556) : Enable after hooking into the reporting service
// https://crbug.com/704259
bool NetworkDelegate::OnCanQueueReportingReport(
const url::Origin& origin) const {
return false;
}
void NetworkDelegate::OnCanSendReportingReports(
std::set<url::Origin> origins,
base::OnceCallback<void(std::set<url::Origin>)> result_callback) const {}
bool NetworkDelegate::OnCanSetReportingClient(const url::Origin& origin,
const GURL& endpoint) const {
return false;
}
bool NetworkDelegate::OnCanUseReportingClient(const url::Origin& origin,
const GURL& endpoint) const {
return false;
}
} // namespace brightray

View file

@ -1,88 +0,0 @@
// Copyright (c) 2012 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-CHROMIUM file.
#ifndef BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
#define BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_
#include <set>
#include <string>
#include <vector>
#include "net/base/network_delegate.h"
namespace brightray {
class NetworkDelegate : public net::NetworkDelegate {
public:
NetworkDelegate();
~NetworkDelegate() override;
protected:
int OnBeforeURLRequest(net::URLRequest* request,
const net::CompletionCallback& callback,
GURL* new_url) override;
int OnBeforeStartTransaction(net::URLRequest* request,
const net::CompletionCallback& callback,
net::HttpRequestHeaders* headers) override;
void OnBeforeSendHeaders(net::URLRequest* request,
const net::ProxyInfo& proxy_info,
const net::ProxyRetryInfoMap& proxy_retry_info,
net::HttpRequestHeaders* headers) override;
void OnStartTransaction(net::URLRequest* request,
const net::HttpRequestHeaders& headers) override;
int OnHeadersReceived(
net::URLRequest* request,
const net::CompletionCallback& callback,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) override;
void OnBeforeRedirect(net::URLRequest* request,
const GURL& new_location) override;
void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnNetworkBytesReceived(net::URLRequest* request,
int64_t bytes_read) override;
void OnNetworkBytesSent(net::URLRequest* request,
int64_t bytes_sent) override;
void OnCompleted(net::URLRequest* request, bool started) override;
void OnURLRequestDestroyed(net::URLRequest* request) override;
void OnPACScriptError(int line_number, const base::string16& error) override;
AuthRequiredResponse OnAuthRequired(
net::URLRequest* request,
const net::AuthChallengeInfo& auth_info,
const AuthCallback& callback,
net::AuthCredentials* credentials) override;
bool OnCanGetCookies(const net::URLRequest& request,
const net::CookieList& cookie_list) override;
bool OnCanSetCookie(const net::URLRequest& request,
const net::CanonicalCookie& cookie_line,
net::CookieOptions* options) override;
bool OnCanAccessFile(const net::URLRequest& request,
const base::FilePath& original_path,
const base::FilePath& absolute_path) const override;
bool OnCanEnablePrivacyMode(
const GURL& url,
const GURL& first_party_for_cookies) const override;
bool OnAreExperimentalCookieFeaturesEnabled() const override;
bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(
const net::URLRequest& request,
const GURL& target_url,
const GURL& referrer_url) const override;
bool OnCanQueueReportingReport(const url::Origin& origin) const override;
void OnCanSendReportingReports(std::set<url::Origin> origins,
base::OnceCallback<void(std::set<url::Origin>)>
result_callback) const override;
bool OnCanSetReportingClient(const url::Origin& origin,
const GURL& endpoint) const override;
bool OnCanUseReportingClient(const url::Origin& origin,
const GURL& endpoint) const override;
private:
std::vector<std::string> ignore_connections_limit_domains_;
DISALLOW_COPY_AND_ASSIGN(NetworkDelegate);
};
} // namespace brightray
#endif // BRIGHTRAY_BROWSER_NETWORK_DELEGATE_H_

View file

@ -4,381 +4,151 @@
#include "brightray/browser/url_request_context_getter.h"
#include <algorithm>
#include <vector>
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "brightray/browser/browser_client.h"
#include "brightray/browser/net/require_ct_delegate.h"
#include "brightray/browser/net_log.h"
#include "brightray/browser/network_delegate.h"
#include "brightray/common/switches.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "brightray/browser/browser_context.h"
#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 "net/base/host_mapping_rules.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_known_logs.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/http/http_auth_filter.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_server_properties_impl.h"
#include "net/log/net_log.h"
#include "net/proxy_resolution/dhcp_pac_file_fetcher_factory.h"
#include "net/proxy_resolution/pac_file_fetcher_impl.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_service.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "services/network/public/cpp/network_switches.h"
#include "storage/browser/quota/special_storage_policy.h"
#include "url/url_constants.h"
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<net::NetworkDelegate>
URLRequestContextGetter::Delegate::CreateNetworkDelegate() {
return nullptr;
}
std::unique_ptr<net::URLRequestJobFactory>
URLRequestContextGetter::Delegate::CreateURLRequestJobFactory(
content::ProtocolHandlerMap* protocol_handlers) {
std::unique_ptr<net::URLRequestJobFactoryImpl> 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_;
DISALLOW_COPY_AND_ASSIGN(ResourceContext);
};
namespace {
// For safe shutdown, must be called before
// URLRequestContextGetter::Handle is destroyed.
void NotifyContextGettersOfShutdownOnIO(
std::unique_ptr<std::vector<scoped_refptr<URLRequestContextGetter>>>
getters) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (auto& context_getter : *getters)
context_getter->NotifyContextShuttingDown();
}
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);
} // namespace
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);
URLRequestContextGetter::Handle::Handle(
base::WeakPtr<BrowserContext> 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();
}
std::unique_ptr<net::CertVerifier>
URLRequestContextGetter::Delegate::CreateCertVerifier(
RequireCTDelegate* ct_delegate) {
return net::CertVerifier::CreateDefault();
scoped_refptr<URLRequestContextGetter>
URLRequestContextGetter::Handle::CreateMainRequestContextGetter(
URLRequestContextGetterFactory* factory) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!main_request_context_getter_.get());
main_request_context_getter_ =
new URLRequestContextGetter(factory, resource_context_.get());
return main_request_context_getter_;
}
net::SSLConfigService*
URLRequestContextGetter::Delegate::CreateSSLConfigService() {
return new net::SSLConfigServiceDefaults;
scoped_refptr<URLRequestContextGetter>
URLRequestContextGetter::Handle::GetMediaRequestContextGetter() const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return main_request_context_getter_;
}
std::vector<std::string>
URLRequestContextGetter::Delegate::GetCookieableSchemes() {
return {"http", "https", "ws", "wss"};
void URLRequestContextGetter::Handle::LazyInitialize() const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (initialized_)
return;
initialized_ = true;
content::BrowserContext::EnsureResourceContextInitialized(
browser_context_.get());
}
void URLRequestContextGetter::Handle::ShutdownOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto context_getters =
std::make_unique<std::vector<scoped_refptr<URLRequestContextGetter>>>();
if (media_request_context_getter_.get())
context_getters->push_back(media_request_context_getter_);
if (main_request_context_getter_.get())
context_getters->push_back(main_request_context_getter_);
if (!context_getters->empty()) {
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&NotifyContextGettersOfShutdownOnIO,
std::move(context_getters)));
}
}
if (!BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this))
delete this;
}
URLRequestContextGetter::URLRequestContextGetter(
Delegate* delegate,
NetLog* net_log,
const base::FilePath& base_path,
bool in_memory,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors)
: delegate_(delegate),
net_log_(net_log),
base_path_(base_path),
in_memory_(in_memory),
io_task_runner_(io_task_runner),
protocol_interceptors_(std::move(protocol_interceptors)),
job_factory_(nullptr),
URLRequestContextGetterFactory* factory,
ResourceContext* resource_context)
: factory_(factory),
resource_context_(resource_context),
url_request_context_(nullptr),
context_shutting_down_(false) {
// Must first be created on the UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
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_);
}
URLRequestContextGetter::~URLRequestContextGetter() {}
URLRequestContextGetter::~URLRequestContextGetter() {
DCHECK(!factory_.get());
DCHECK(!url_request_context_);
}
void URLRequestContextGetter::NotifyContextShuttingDown() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
void URLRequestContextGetter::NotifyContextShutdownOnIO() {
context_shutting_down_ = true;
cookie_change_sub_.reset();
http_network_session_.reset();
http_auth_preferences_.reset();
host_mapping_rules_.reset();
url_request_context_.reset();
storage_.reset();
ct_delegate_.reset();
url_request_context_ = nullptr;
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();
factory_.reset();
}
net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (context_shutting_down_)
return nullptr;
if (!url_request_context_.get()) {
ct_delegate_.reset(new RequireCTDelegate);
auto& command_line = *base::CommandLine::ForCurrentProcess();
url_request_context_.reset(new net::URLRequestContext);
// --log-net-log
if (net_log_) {
net_log_->StartLogging();
url_request_context_->set_net_log(net_log_);
if (factory_.get() && !url_request_context_ && !context_shutting_down_) {
url_request_context_ = factory_->Create();
if (resource_context_) {
resource_context_->request_context_ = url_request_context_;
}
storage_.reset(
new net::URLRequestContextStorage(url_request_context_.get()));
storage_->set_network_delegate(delegate_->CreateNetworkDelegate());
auto cookie_path = in_memory_
? base::FilePath()
: base_path_.Append(FILE_PATH_LITERAL("Cookies"));
std::unique_ptr<net::CookieStore> 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<net::CookieMonster*>(url_request_context_->cookie_store());
cookie_monster->SetCookieableSchemes(delegate_->GetCookieableSchemes());
// 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));
storage_->set_channel_id_service(std::make_unique<net::ChannelIDService>(
new net::DefaultChannelIDStore(nullptr)));
storage_->set_http_user_agent_settings(
base::WrapUnique(new net::StaticHttpUserAgentSettings(
net::HttpUtil::GenerateAcceptLanguageHeader(
BrowserClient::Get()->GetApplicationLocale()),
user_agent_)));
std::unique_ptr<net::HostResolver> host_resolver(
net::HostResolver::CreateDefaultResolver(nullptr));
// --host-resolver-rules
if (command_line.HasSwitch(network::switches::kHostResolverRules)) {
std::unique_ptr<net::MappedHostResolver> remapped_resolver(
new net::MappedHostResolver(std::move(host_resolver)));
remapped_resolver->SetRulesFromString(command_line.GetSwitchValueASCII(
network::switches::kHostResolverRules));
host_resolver = std::move(remapped_resolver);
}
// --proxy-server
if (command_line.HasSwitch(switches::kNoProxyServer)) {
storage_->set_proxy_resolution_service(
net::ProxyResolutionService::CreateDirect());
} else if (command_line.HasSwitch(switches::kProxyServer)) {
net::ProxyConfig proxy_config;
proxy_config.proxy_rules().ParseFromString(
command_line.GetSwitchValueASCII(switches::kProxyServer));
proxy_config.proxy_rules().bypass_rules.ParseFromString(
command_line.GetSwitchValueASCII(switches::kProxyBypassList));
storage_->set_proxy_resolution_service(
net::ProxyResolutionService::CreateFixed(proxy_config));
} else if (command_line.HasSwitch(switches::kProxyPacUrl)) {
auto proxy_config = net::ProxyConfig::CreateFromCustomPacURL(
GURL(command_line.GetSwitchValueASCII(switches::kProxyPacUrl)));
proxy_config.set_pac_mandatory(true);
storage_->set_proxy_resolution_service(
net::ProxyResolutionService::CreateFixed(proxy_config));
} else {
storage_->set_proxy_resolution_service(
net::ProxyResolutionService::CreateUsingSystemProxyResolver(
std::move(proxy_config_service_), net_log_));
}
std::vector<std::string> schemes;
schemes.push_back(std::string("basic"));
schemes.push_back(std::string("digest"));
schemes.push_back(std::string("ntlm"));
schemes.push_back(std::string("negotiate"));
#if defined(OS_POSIX)
http_auth_preferences_.reset(
new net::HttpAuthPreferences(schemes, std::string()));
#else
http_auth_preferences_.reset(new net::HttpAuthPreferences(schemes));
#endif
// --auth-server-whitelist
if (command_line.HasSwitch(switches::kAuthServerWhitelist)) {
http_auth_preferences_->SetServerWhitelist(
command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist));
}
// --auth-negotiate-delegate-whitelist
if (command_line.HasSwitch(switches::kAuthNegotiateDelegateWhitelist)) {
http_auth_preferences_->SetDelegateWhitelist(
command_line.GetSwitchValueASCII(
switches::kAuthNegotiateDelegateWhitelist));
}
auto auth_handler_factory = net::HttpAuthHandlerRegistryFactory::Create(
http_auth_preferences_.get(), host_resolver.get());
std::unique_ptr<net::TransportSecurityState> transport_security_state =
base::WrapUnique(new net::TransportSecurityState);
transport_security_state->SetRequireCTDelegate(ct_delegate_.get());
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_http_auth_handler_factory(std::move(auth_handler_factory));
std::unique_ptr<net::HttpServerProperties> server_properties(
new net::HttpServerPropertiesImpl);
storage_->set_http_server_properties(std::move(server_properties));
std::unique_ptr<net::MultiLogCTVerifier> ct_verifier =
std::make_unique<net::MultiLogCTVerifier>();
ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
storage_->set_cert_transparency_verifier(std::move(ct_verifier));
storage_->set_ct_policy_enforcer(std::make_unique<net::CTPolicyEnforcer>());
net::HttpNetworkSession::Params network_session_params;
network_session_params.ignore_certificate_errors = false;
// --disable-http2
if (command_line.HasSwitch(switches::kDisableHttp2))
network_session_params.enable_http2 = false;
// --ignore-certificate-errors
if (command_line.HasSwitch(::switches::kIgnoreCertificateErrors))
network_session_params.ignore_certificate_errors = true;
// --host-rules
if (command_line.HasSwitch(switches::kHostRules)) {
host_mapping_rules_.reset(new net::HostMappingRules);
host_mapping_rules_->SetRulesFromString(
command_line.GetSwitchValueASCII(switches::kHostRules));
network_session_params.host_mapping_rules = *host_mapping_rules_.get();
}
// Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
storage_->set_host_resolver(std::move(host_resolver));
net::HttpNetworkSession::Context network_session_context;
net::URLRequestContextBuilder::SetHttpNetworkSessionComponents(
url_request_context_.get(), &network_session_context);
http_network_session_.reset(new net::HttpNetworkSession(
network_session_params, network_session_context));
std::unique_ptr<net::HttpCache::BackendFactory> backend;
if (in_memory_) {
backend = net::HttpCache::DefaultBackend::InMemory(0);
} else {
backend.reset(delegate_->CreateHttpCacheBackendFactory(base_path_));
}
storage_->set_http_transaction_factory(std::make_unique<net::HttpCache>(
content::CreateDevToolsNetworkTransactionFactory(
http_network_session_.get()),
std::move(backend), false));
std::unique_ptr<net::URLRequestJobFactory> job_factory =
delegate_->CreateURLRequestJobFactory(&protocol_handlers_);
job_factory_ = job_factory.get();
// Set up interceptors in the reverse order.
std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
std::move(job_factory);
if (!protocol_interceptors_.empty()) {
for (auto it = protocol_interceptors_.rbegin();
it != protocol_interceptors_.rend(); ++it) {
top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
std::move(top_job_factory), std::move(*it)));
}
protocol_interceptors_.clear();
}
storage_->set_job_factory(std::move(top_job_factory));
}
return url_request_context_.get();
return url_request_context_;
}
scoped_refptr<base::SingleThreadTaskRunner>

View file

@ -5,16 +5,8 @@
#ifndef BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
#define BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "net/http/http_cache.h"
#include "net/http/transport_security_state.h"
#include "net/http/url_security_manager.h"
#include "brightray/browser/net/url_request_context_getter_factory.h"
#include "content/public/browser/resource_context.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
@ -22,99 +14,64 @@
#include "base/debug/leak_tracker.h"
#endif
namespace base {
class MessageLoop;
}
namespace net {
class HostMappingRules;
class HostResolver;
class HttpAuthPreferences;
class NetworkDelegate;
class ProxyConfigService;
class URLRequestContextStorage;
class URLRequestJobFactory;
} // namespace net
namespace brightray {
class RequireCTDelegate;
class NetLog;
class BrowserContext;
class ResourceContext;
class URLRequestContextGetter : public net::URLRequestContextGetter {
public:
class Delegate {
public:
Delegate() {}
virtual ~Delegate() {}
virtual std::unique_ptr<net::NetworkDelegate> CreateNetworkDelegate();
virtual std::string GetUserAgent();
virtual std::unique_ptr<net::URLRequestJobFactory>
CreateURLRequestJobFactory(content::ProtocolHandlerMap* protocol_handlers);
virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory(
const base::FilePath& base_path);
virtual std::unique_ptr<net::CertVerifier> CreateCertVerifier(
RequireCTDelegate* ct_delegate);
virtual net::SSLConfigService* CreateSSLConfigService();
virtual std::vector<std::string> GetCookieableSchemes();
virtual void NotifyCookieChange(const net::CanonicalCookie& cookie,
bool removed,
net::CookieChangeCause cause) {}
};
URLRequestContextGetter(
Delegate* delegate,
NetLog* net_log,
const base::FilePath& base_path,
bool in_memory,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector protocol_interceptors);
// net::CookieChangeDispatcher::CookieChangedCallback implementation.
void OnCookieChanged(const net::CanonicalCookie& cookie,
net::CookieChangeCause cause);
URLRequestContextGetter(URLRequestContextGetterFactory* factory,
ResourceContext* resource_context);
// net::URLRequestContextGetter:
net::URLRequestContext* GetURLRequestContext() override;
scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
const override;
net::HostResolver* host_resolver();
net::URLRequestJobFactory* job_factory() const { return job_factory_; }
void NotifyContextShutdownOnIO();
// Discard reference to URLRequestContext and inform observers to
// shutdown. Must be called only on IO thread.
void NotifyContextShuttingDown();
private:
friend class BrowserContext;
// Responsible for destroying URLRequestContextGetter
// on the IO thread.
class Handle {
public:
explicit Handle(base::WeakPtr<BrowserContext> browser_context);
~Handle();
scoped_refptr<URLRequestContextGetter> CreateMainRequestContextGetter(
URLRequestContextGetterFactory* factory);
content::ResourceContext* GetResourceContext() const;
scoped_refptr<URLRequestContextGetter> GetMediaRequestContextGetter() const;
void ShutdownOnUIThread();
private:
void LazyInitialize() const;
scoped_refptr<URLRequestContextGetter> main_request_context_getter_;
scoped_refptr<URLRequestContextGetter> media_request_context_getter_;
std::unique_ptr<ResourceContext> resource_context_;
base::WeakPtr<BrowserContext> 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<base::SingleThreadTaskRunner> io_task_runner_;
std::string user_agent_;
#if DCHECK_IS_ON()
base::debug::LeakTracker<URLRequestContextGetter> leak_tracker_;
#endif
std::unique_ptr<RequireCTDelegate> ct_delegate_;
std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
std::unique_ptr<net::URLRequestContextStorage> storage_;
std::unique_ptr<net::URLRequestContext> url_request_context_;
std::unique_ptr<net::HostMappingRules> host_mapping_rules_;
std::unique_ptr<net::HttpAuthPreferences> http_auth_preferences_;
std::unique_ptr<net::HttpNetworkSession> http_network_session_;
std::unique_ptr<net::CookieChangeSubscription> cookie_change_sub_;
content::ProtocolHandlerMap protocol_handlers_;
content::URLRequestInterceptorScopedVector protocol_interceptors_;
net::URLRequestJobFactory* job_factory_; // weak ref
std::unique_ptr<URLRequestContextGetterFactory> factory_;
ResourceContext* resource_context_;
net::URLRequestContext* url_request_context_;
bool context_shutting_down_;
DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);