fix: initialize system network context from IOThread

This commit is contained in:
deepak1556 2018-11-07 19:54:05 +05:30
parent 666a106fa8
commit 57356036db
5 changed files with 105 additions and 98 deletions

View file

@ -109,7 +109,8 @@ void BrowserProcessImpl::PreCreateThreads(
net_log_->net_export_file_writer()->Initialize(); net_log_->net_export_file_writer()->Initialize();
// Manage global state of net and other IO thread related. // Manage global state of net and other IO thread related.
io_thread_ = std::make_unique<IOThread>(net_log_.get()); io_thread_ = std::make_unique<IOThread>(
net_log_.get(), system_network_context_manager_.get());
} }
void BrowserProcessImpl::PostDestroyThreads() { void BrowserProcessImpl::PostDestroyThreads() {
@ -153,7 +154,7 @@ net::URLRequestContextGetter* BrowserProcessImpl::system_request_context() {
scoped_refptr<network::SharedURLLoaderFactory> scoped_refptr<network::SharedURLLoaderFactory>
BrowserProcessImpl::shared_url_loader_factory() { BrowserProcessImpl::shared_url_loader_factory() {
return nullptr; return system_network_context_manager()->GetSharedURLLoaderFactory();
} }
variations::VariationsService* BrowserProcessImpl::variations_service() { variations::VariationsService* BrowserProcessImpl::variations_service() {

View file

@ -3,57 +3,31 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/io_thread.h" #include "atom/browser/io_thread.h"
#include "atom/common/options_switches.h"
#include <utility>
#include "components/net_log/chrome_net_log.h" #include "components/net_log/chrome_net_log.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_instance.h"
#include "net/cert/caching_cert_verifier.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/multi_threaded_cert_verifier.h"
#include "net/proxy_resolution/proxy_resolution_service.h" #include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/url_request/url_request_context.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_getter.h"
#include "services/network/network_service.h" #include "services/network/network_service.h"
#include "services/network/url_request_context_builder_mojo.h"
#if defined(USE_NSS_CERTS)
#include "net/cert_net/nss_ocsp.h"
#endif
#if defined(OS_LINUX) || defined(OS_MACOSX)
#include "net/cert/cert_net_fetcher.h"
#include "net/cert_net/cert_net_fetcher_impl.h"
#endif
using content::BrowserThread; using content::BrowserThread;
namespace { IOThread::IOThread(net_log::ChromeNetLog* net_log,
SystemNetworkContextManager* system_network_context_manager)
network::mojom::HttpAuthStaticParamsPtr CreateHttpAuthStaticParams() { : net_log_(net_log) {
network::mojom::HttpAuthStaticParamsPtr auth_static_params =
network::mojom::HttpAuthStaticParams::New();
auth_static_params->supported_schemes = {"basic", "digest", "ntlm",
"negotiate"};
return auth_static_params;
}
network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams(
const base::CommandLine& command_line) {
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
network::mojom::HttpAuthDynamicParams::New();
auth_dynamic_params->server_whitelist =
command_line.GetSwitchValueASCII(atom::switches::kAuthServerWhitelist);
auth_dynamic_params->delegate_whitelist = command_line.GetSwitchValueASCII(
atom::switches::kAuthNegotiateDelegateWhitelist);
return auth_dynamic_params;
}
} // namespace
IOThread::IOThread(net_log::ChromeNetLog* net_log) : net_log_(net_log) {
BrowserThread::SetIOThreadDelegate(this); BrowserThread::SetIOThreadDelegate(this);
system_network_context_manager->SetUp(
&network_context_request_, &network_context_params_,
&http_auth_static_params_, &http_auth_dynamic_params_);
} }
IOThread::~IOThread() { IOThread::~IOThread() {
@ -61,53 +35,31 @@ IOThread::~IOThread() {
} }
void IOThread::Init() { void IOThread::Init() {
std::unique_ptr<network::URLRequestContextBuilderMojo> builder =
std::make_unique<network::URLRequestContextBuilderMojo>();
auto cert_verifier = std::make_unique<net::CachingCertVerifier>(
std::make_unique<net::MultiThreadedCertVerifier>(
net::CertVerifyProc::CreateDefault()));
builder->SetCertVerifier(std::move(cert_verifier));
// Create the network service, so that shared host resolver // Create the network service, so that shared host resolver
// gets created which is required to set the auth preferences below. // gets created which is required to set the auth preferences below.
auto& command_line = *base::CommandLine::ForCurrentProcess(); network::NetworkService* network_service = content::GetNetworkServiceImpl();
auto* network_service = content::GetNetworkServiceImpl(); network_service->SetUpHttpAuth(std::move(http_auth_static_params_));
network_service->SetUpHttpAuth(CreateHttpAuthStaticParams()); network_service->ConfigureHttpAuthPrefs(std::move(http_auth_dynamic_params_));
network_service->ConfigureHttpAuthPrefs(
CreateHttpAuthDynamicParams(command_line));
net::URLRequestContextBuilder builder; system_network_context_ =
// TODO(deepak1556): We need to respoect user proxy configurations, network_service
// the following initialization has to happen before any request ->CreateNetworkContextWithBuilder(std::move(network_context_request_),
// contexts are utilized by the io thread, so that proper cert validation std::move(network_context_params_),
// take place, solutions: std::move(builder),
// 1) Use the request context from default partition, but since &system_request_context_)
// an app can completely run on a custom session without ever creating .release();
// the default session, we will have to force create the default session
// in those scenarios.
// 2) Add a new api on app module that sets the proxy configuration
// for the global requests, like the cert fetchers below and
// geolocation requests.
// 3) There is also ongoing work in upstream which will eventually allow
// localizing these global fetchers to their own URLRequestContexts.
builder.set_proxy_resolution_service(
net::ProxyResolutionService::CreateDirect());
url_request_context_ = builder.Build();
url_request_context_getter_ = new net::TrivialURLRequestContextGetter(
url_request_context_.get(), base::ThreadTaskRunnerHandle::Get());
#if defined(USE_NSS_CERTS)
net::SetURLRequestContextForNSSHttpIO(url_request_context_.get());
#endif
#if defined(OS_LINUX) || defined(OS_MACOSX)
net::SetGlobalCertNetFetcher(
net::CreateCertNetFetcher(url_request_context_.get()));
#endif
} }
void IOThread::CleanUp() { void IOThread::CleanUp() {
#if defined(USE_NSS_CERTS) system_request_context_->proxy_resolution_service()->OnShutdown();
net::SetURLRequestContextForNSSHttpIO(nullptr);
#endif
#if defined(OS_LINUX) || defined(OS_MACOSX)
net::ShutdownGlobalCertNetFetcher();
#endif
// Explicitly release before the IO thread gets destroyed.
url_request_context_.reset();
url_request_context_getter_ = nullptr;
if (net_log_) if (net_log_)
net_log_->ShutDownBeforeTaskScheduler(); net_log_->ShutDownBeforeTaskScheduler();

View file

@ -7,14 +7,14 @@
#include <memory> #include <memory>
#include "atom/browser/net/system_network_context_manager.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "content/public/browser/browser_thread_delegate.h" #include "content/public/browser/browser_thread_delegate.h"
#include "services/network/public/mojom/network_service.mojom.h"
namespace net { namespace net {
class URLRequestContext; class URLRequestContext;
class URLRequestContextGetter; }
} // namespace net
namespace net_log { namespace net_log {
class ChromeNetLog; class ChromeNetLog;
@ -22,13 +22,11 @@ class ChromeNetLog;
class IOThread : public content::BrowserThreadDelegate { class IOThread : public content::BrowserThreadDelegate {
public: public:
explicit IOThread(net_log::ChromeNetLog* net_log); explicit IOThread(
net_log::ChromeNetLog* net_log,
SystemNetworkContextManager* system_network_context_manager);
~IOThread() override; ~IOThread() override;
net::URLRequestContextGetter* GetRequestContext() {
return url_request_context_getter_.get();
}
protected: protected:
// BrowserThreadDelegate Implementation, runs on the IO thread. // BrowserThreadDelegate Implementation, runs on the IO thread.
void Init() override; void Init() override;
@ -38,8 +36,28 @@ class IOThread : public content::BrowserThreadDelegate {
// The NetLog is owned by the browser process, to allow logging from other // The NetLog is owned by the browser process, to allow logging from other
// threads during shutdown, but is used most frequently on the IOThread. // threads during shutdown, but is used most frequently on the IOThread.
net_log::ChromeNetLog* net_log_; net_log::ChromeNetLog* net_log_;
std::unique_ptr<net::URLRequestContext> url_request_context_;
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; // When the network service is disabled, this holds on to a
// content::NetworkContext class that owns |system_request_context_|.
// TODO(deepak1556): primary network context has to be destroyed after
// other active contexts, but since the ownership of latter is not released
// before IO thread is destroyed, it results in a DCHECK failure.
// We leak the reference to primary context to workaround this issue,
// since there is only one instance for the entire lifetime of app, it is
// safe.
network::mojom::NetworkContext* system_network_context_;
net::URLRequestContext* system_request_context_;
// These are set on the UI thread, and then consumed during initialization on
// the IO thread.
network::mojom::NetworkContextRequest network_context_request_;
network::mojom::NetworkContextParamsPtr network_context_params_;
// Initial HTTP auth configuration used when setting up the NetworkService on
// the IO Thread. Future updates are sent using the NetworkService mojo
// interface, but initial state needs to be set non-racily.
network::mojom::HttpAuthStaticParamsPtr http_auth_static_params_;
network::mojom::HttpAuthDynamicParamsPtr http_auth_dynamic_params_;
DISALLOW_COPY_AND_ASSIGN(IOThread); DISALLOW_COPY_AND_ASSIGN(IOThread);
}; };

View file

@ -8,6 +8,8 @@
#include <utility> #include <utility>
#include "atom/browser/io_thread.h" #include "atom/browser/io_thread.h"
#include "atom/common/options_switches.h"
#include "base/command_line.h"
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" #include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
@ -26,6 +28,33 @@
base::LazyInstance<SystemNetworkContextManager>::Leaky base::LazyInstance<SystemNetworkContextManager>::Leaky
g_system_network_context_manager = LAZY_INSTANCE_INITIALIZER; g_system_network_context_manager = LAZY_INSTANCE_INITIALIZER;
namespace {
network::mojom::HttpAuthStaticParamsPtr CreateHttpAuthStaticParams() {
network::mojom::HttpAuthStaticParamsPtr auth_static_params =
network::mojom::HttpAuthStaticParams::New();
auth_static_params->supported_schemes = {"basic", "digest", "ntlm",
"negotiate"};
return auth_static_params;
}
network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams() {
auto* command_line = base::CommandLine::ForCurrentProcess();
network::mojom::HttpAuthDynamicParamsPtr auth_dynamic_params =
network::mojom::HttpAuthDynamicParams::New();
auth_dynamic_params->server_whitelist =
command_line->GetSwitchValueASCII(atom::switches::kAuthServerWhitelist);
auth_dynamic_params->delegate_whitelist = command_line->GetSwitchValueASCII(
atom::switches::kAuthNegotiateDelegateWhitelist);
return auth_dynamic_params;
}
} // namespace
// SharedURLLoaderFactory backed by a SystemNetworkContextManager and its // SharedURLLoaderFactory backed by a SystemNetworkContextManager and its
// network context. Transparently handles crashes. // network context. Transparently handles crashes.
class SystemNetworkContextManager::URLLoaderFactoryForSystem class SystemNetworkContextManager::URLLoaderFactoryForSystem
@ -137,7 +166,9 @@ SystemNetworkContextManager::CreateDefaultNetworkContextParams() {
void SystemNetworkContextManager::SetUp( void SystemNetworkContextManager::SetUp(
network::mojom::NetworkContextRequest* network_context_request, network::mojom::NetworkContextRequest* network_context_request,
network::mojom::NetworkContextParamsPtr* network_context_params) { network::mojom::NetworkContextParamsPtr* network_context_params,
network::mojom::HttpAuthStaticParamsPtr* http_auth_static_params,
network::mojom::HttpAuthDynamicParamsPtr* http_auth_dynamic_params) {
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
*network_context_request = mojo::MakeRequest(&io_thread_network_context_); *network_context_request = mojo::MakeRequest(&io_thread_network_context_);
*network_context_params = CreateNetworkContextParams(); *network_context_params = CreateNetworkContextParams();
@ -146,6 +177,8 @@ void SystemNetworkContextManager::SetUp(
// CreateNetworkContextParams() can only be called once. // CreateNetworkContextParams() can only be called once.
*network_context_params = CreateDefaultNetworkContextParams(); *network_context_params = CreateDefaultNetworkContextParams();
} }
*http_auth_static_params = CreateHttpAuthStaticParams();
*http_auth_dynamic_params = CreateHttpAuthDynamicParams();
} }
SystemNetworkContextManager::SystemNetworkContextManager() SystemNetworkContextManager::SystemNetworkContextManager()
@ -162,8 +195,8 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
return; return;
// network_service->SetUpHttpAuth(CreateHttpAuthStaticParams()); network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
// network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams()); network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
// The system NetworkContext must be created first, since it sets // The system NetworkContext must be created first, since it sets
// |primary_network_context| to true. // |primary_network_context| to true.

View file

@ -50,8 +50,11 @@ class SystemNetworkContextManager {
// help set up the IOThread's in-process URLRequestContext. // help set up the IOThread's in-process URLRequestContext.
// //
// Must be called before the system NetworkContext is first used. // Must be called before the system NetworkContext is first used.
void SetUp(network::mojom::NetworkContextRequest* network_context_request, void SetUp(
network::mojom::NetworkContextParamsPtr* network_context_params); network::mojom::NetworkContextRequest* network_context_request,
network::mojom::NetworkContextParamsPtr* network_context_params,
network::mojom::HttpAuthStaticParamsPtr* http_auth_static_params,
network::mojom::HttpAuthDynamicParamsPtr* http_auth_dynamic_params);
// Returns the System NetworkContext. May only be called after SetUp(). Does // Returns the System NetworkContext. May only be called after SetUp(). Does
// any initialization of the NetworkService that may be needed when first // any initialization of the NetworkService that may be needed when first