diff --git a/atom/browser/api/atom_api_cookies.cc b/atom/browser/api/atom_api_cookies.cc index 2f226d9210db6..c591a403f6452 100644 --- a/atom/browser/api/atom_api_cookies.cc +++ b/atom/browser/api/atom_api_cookies.cc @@ -5,7 +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/browser/cookie_change_notifier.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" @@ -56,20 +56,21 @@ struct Converter { }; template <> -struct Converter { - static v8::Local ToV8(v8::Isolate* isolate, - const net::CookieChangeCause& val) { +struct Converter { + static v8::Local ToV8( + v8::Isolate* isolate, + const network::mojom::CookieChangeCause& val) { switch (val) { - case net::CookieChangeCause::INSERTED: - case net::CookieChangeCause::EXPLICIT: + case network::mojom::CookieChangeCause::INSERTED: + case network::mojom::CookieChangeCause::EXPLICIT: return mate::StringToV8(isolate, "explicit"); - case net::CookieChangeCause::OVERWRITE: + case network::mojom::CookieChangeCause::OVERWRITE: return mate::StringToV8(isolate, "overwrite"); - case net::CookieChangeCause::EXPIRED: + case network::mojom::CookieChangeCause::EXPIRED: return mate::StringToV8(isolate, "expired"); - case net::CookieChangeCause::EVICTED: + case network::mojom::CookieChangeCause::EVICTED: return mate::StringToV8(isolate, "evicted"); - case net::CookieChangeCause::EXPIRED_OVERWRITE: + case network::mojom::CookieChangeCause::EXPIRED_OVERWRITE: return mate::StringToV8(isolate, "expired-overwrite"); default: return mate::StringToV8(isolate, "unknown"); @@ -255,9 +256,8 @@ Cookies::Cookies(v8::Isolate* isolate, AtomBrowserContext* browser_context) : browser_context_(browser_context) { Init(isolate); cookie_change_subscription_ = - browser_context->GetRequestContextDelegate() - ->RegisterCookieChangeCallback( - base::Bind(&Cookies::OnCookieChanged, base::Unretained(this))); + browser_context_->cookie_change_notifier()->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 8a83a64ca1012..73851d5892bc5 100644 --- a/atom/browser/api/atom_api_cookies.h +++ b/atom/browser/api/atom_api_cookies.h @@ -55,7 +55,7 @@ class Cookies : public mate::TrackableObject { void Set(const base::DictionaryValue& details, const SetCallback& callback); void FlushStore(const base::Closure& callback); - // AtomBrowserContext::RegisterCookieChangeCallback subscription: + // CookieChangeNotifier subscription: void OnCookieChanged(const CookieDetails*); private: diff --git a/atom/browser/api/atom_api_net_log.cc b/atom/browser/api/atom_api_net_log.cc index 299ef76f83a8a..f15b3840b89ea 100644 --- a/atom/browser/api/atom_api_net_log.cc +++ b/atom/browser/api/atom_api_net_log.cc @@ -3,13 +3,19 @@ // found in the LICENSE file. #include "atom/browser/api/atom_api_net_log.h" -#include "atom/browser/atom_browser_client.h" + +#include + +#include "atom/browser/atom_browser_context.h" +#include "atom/browser/atom_browser_main_parts.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" -#include "base/callback.h" -#include "content/public/common/content_switches.h" +#include "base/command_line.h" +#include "components/net_log/chrome_net_log.h" +#include "content/public/browser/storage_partition.h" #include "native_mate/dictionary.h" #include "native_mate/handle.h" +#include "net/url_request/url_request_context_getter.h" #include "atom/common/node_includes.h" @@ -17,17 +23,17 @@ namespace atom { namespace api { -NetLog::NetLog(v8::Isolate* isolate) { +NetLog::NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context) + : browser_context_(browser_context) { Init(isolate); - net_log_ = atom::AtomBrowserClient::Get()->GetNetLog(); + net_log_writer_ = + atom::AtomBrowserMainParts::Get()->net_log()->net_export_file_writer(); + net_log_writer_->AddObserver(this); } -NetLog::~NetLog() {} - -// static -v8::Local NetLog::Create(v8::Isolate* isolate) { - return mate::CreateHandle(isolate, new NetLog(isolate)).ToV8(); +NetLog::~NetLog() { + net_log_writer_->RemoveObserver(this); } void NetLog::StartLogging(mate::Arguments* args) { @@ -37,22 +43,82 @@ void NetLog::StartLogging(mate::Arguments* args) { return; } - net_log_->StartDynamicLogging(log_path); + net_log::NetExportFileWriter::URLRequestContextGetterList context_getters = { + browser_context_->GetRequestContext()}; + + // TODO(deepak1556): Provide more flexibility to this module + // by allowing customizations on the capturing options. + net_log_writer_->StartNetLog( + log_path, net::NetLogCaptureMode::Default(), + net_log::NetExportFileWriter::kNoLimit /* file size limit */, + base::CommandLine::ForCurrentProcess()->GetCommandLineString(), + std::string(), context_getters); +} + +std::string NetLog::GetLoggingState() const { + if (!net_log_state_) + return std::string(); + const base::Value* current_log_state = + net_log_state_->FindKeyOfType("state", base::Value::Type::STRING); + if (!current_log_state) + return std::string(); + return current_log_state->GetString(); } -bool NetLog::IsCurrentlyLogging() { - return net_log_->IsDynamicLogging(); +bool NetLog::IsCurrentlyLogging() const { + const std::string log_state = GetLoggingState(); + return (log_state == "STARTING_LOG") || (log_state == "LOGGING"); } -base::FilePath::StringType NetLog::GetCurrentlyLoggingPath() { - return net_log_->GetDynamicLoggingPath().value(); +std::string NetLog::GetCurrentlyLoggingPath() const { + // Net log exporter has a default path which will be used + // when no log path is provided, but since we don't allow + // net log capture without user provided file path, this + // check is completely safe. + if (IsCurrentlyLogging()) { + const base::Value* current_log_path = + net_log_state_->FindKeyOfType("file", base::Value::Type::STRING); + if (current_log_path) + return current_log_path->GetString(); + } + + return std::string(); } void NetLog::StopLogging(mate::Arguments* args) { - base::OnceClosure callback; - args->GetNext(&callback); + net_log::NetExportFileWriter::FilePathCallback callback; + if (!args->GetNext(&callback)) { + args->ThrowError("Invalid callback function"); + return; + } + + if (IsCurrentlyLogging()) { + stop_callback_queue_.emplace_back(callback); + net_log_writer_->StopNetLog(nullptr, nullptr); + } else { + callback.Run(base::FilePath()); + } +} - net_log_->StopDynamicLogging(std::move(callback)); +void NetLog::OnNewState(const base::DictionaryValue& state) { + net_log_state_ = state.CreateDeepCopy(); + + if (stop_callback_queue_.empty()) + return; + + if (GetLoggingState() == "NOT_LOGGING") { + for (auto& callback : stop_callback_queue_) { + if (!callback.is_null()) + net_log_writer_->GetFilePathToCompletedLog(callback); + } + stop_callback_queue_.clear(); + } +} + +// static +mate::Handle NetLog::Create(v8::Isolate* isolate, + AtomBrowserContext* browser_context) { + return mate::CreateHandle(isolate, new NetLog(isolate, browser_context)); } // static @@ -63,28 +129,9 @@ void NetLog::BuildPrototype(v8::Isolate* isolate, .SetProperty("currentlyLogging", &NetLog::IsCurrentlyLogging) .SetProperty("currentlyLoggingPath", &NetLog::GetCurrentlyLoggingPath) .SetMethod("startLogging", &NetLog::StartLogging) - .SetMethod("_stopLogging", &NetLog::StopLogging); + .SetMethod("stopLogging", &NetLog::StopLogging); } } // namespace api } // namespace atom - -namespace { - -using atom::api::NetLog; - -void Initialize(v8::Local exports, - v8::Local unused, - v8::Local context, - void* priv) { - v8::Isolate* isolate = context->GetIsolate(); - - mate::Dictionary dict(isolate, exports); - dict.Set("netLog", NetLog::Create(isolate)); - dict.Set("NetLog", NetLog::GetConstructor(isolate)->GetFunction()); -} - -} // namespace - -NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net_log, Initialize) diff --git a/atom/browser/api/atom_api_net_log.h b/atom/browser/api/atom_api_net_log.h index dd68ac306c964..1afe0b43597f1 100644 --- a/atom/browser/api/atom_api_net_log.h +++ b/atom/browser/api/atom_api_net_log.h @@ -5,32 +5,50 @@ #ifndef ATOM_BROWSER_API_ATOM_API_NET_LOG_H_ #define ATOM_BROWSER_API_ATOM_API_NET_LOG_H_ +#include +#include #include -#include "brightray/browser/net_log.h" -#include "native_mate/wrappable.h" + +#include "atom/browser/api/trackable_object.h" +#include "base/callback.h" +#include "base/values.h" +#include "components/net_log/net_export_file_writer.h" +#include "native_mate/handle.h" namespace atom { +class AtomBrowserContext; + namespace api { -class NetLog : public mate::Wrappable { +class NetLog : public mate::TrackableObject, + public net_log::NetExportFileWriter::StateObserver { public: - static v8::Local Create(v8::Isolate* isolate); + static mate::Handle Create(v8::Isolate* isolate, + AtomBrowserContext* browser_context); static void BuildPrototype(v8::Isolate* isolate, v8::Local prototype); void StartLogging(mate::Arguments* args); - bool IsCurrentlyLogging(); - base::FilePath::StringType GetCurrentlyLoggingPath(); + std::string GetLoggingState() const; + bool IsCurrentlyLogging() const; + std::string GetCurrentlyLoggingPath() const; void StopLogging(mate::Arguments* args); protected: - explicit NetLog(v8::Isolate* isolate); + explicit NetLog(v8::Isolate* isolate, AtomBrowserContext* browser_context); ~NetLog() override; + // net_log::NetExportFileWriter::StateObserver implementation + void OnNewState(const base::DictionaryValue& state) override; + private: - brightray::NetLog* net_log_; + AtomBrowserContext* browser_context_; + net_log::NetExportFileWriter* net_log_writer_; + std::list + stop_callback_queue_; + std::unique_ptr net_log_state_; DISALLOW_COPY_AND_ASSIGN(NetLog); }; diff --git a/atom/browser/api/atom_api_protocol.cc b/atom/browser/api/atom_api_protocol.cc index 5e1f991ad8dcd..49fa2d9cef6a0 100644 --- a/atom/browser/api/atom_api_protocol.cc +++ b/atom/browser/api/atom_api_protocol.cc @@ -83,7 +83,8 @@ void Protocol::UnregisterProtocol(const std::string& scheme, mate::Arguments* args) { CompletionCallback callback; args->GetNext(&callback); - auto* getter = browser_context_->GetRequestContext(); + auto* getter = static_cast( + browser_context_->GetRequestContext()); content::BrowserThread::PostTaskAndReplyWithResult( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&Protocol::UnregisterProtocolInIO, @@ -93,10 +94,9 @@ void Protocol::UnregisterProtocol(const std::string& scheme, // static Protocol::ProtocolError Protocol::UnregisterProtocolInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, const std::string& scheme) { - auto* job_factory = static_cast( - request_context_getter->job_factory()); + auto* job_factory = request_context_getter->job_factory(); if (!job_factory->HasProtocolHandler(scheme)) return PROTOCOL_NOT_REGISTERED; job_factory->SetProtocolHandler(scheme, nullptr); @@ -105,7 +105,8 @@ Protocol::ProtocolError Protocol::UnregisterProtocolInIO( void Protocol::IsProtocolHandled(const std::string& scheme, const BooleanCallback& callback) { - auto* getter = browser_context_->GetRequestContext(); + auto* getter = static_cast( + browser_context_->GetRequestContext()); content::BrowserThread::PostTaskAndReplyWithResult( content::BrowserThread::IO, FROM_HERE, base::Bind(&Protocol::IsProtocolHandledInIO, base::RetainedRef(getter), @@ -115,7 +116,7 @@ void Protocol::IsProtocolHandled(const std::string& scheme, // static bool Protocol::IsProtocolHandledInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, const std::string& scheme) { return request_context_getter->job_factory()->IsHandledProtocol(scheme); } @@ -124,7 +125,8 @@ void Protocol::UninterceptProtocol(const std::string& scheme, mate::Arguments* args) { CompletionCallback callback; args->GetNext(&callback); - auto* getter = browser_context_->GetRequestContext(); + auto* getter = static_cast( + browser_context_->GetRequestContext()); content::BrowserThread::PostTaskAndReplyWithResult( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&Protocol::UninterceptProtocolInIO, @@ -134,11 +136,9 @@ void Protocol::UninterceptProtocol(const std::string& scheme, // static Protocol::ProtocolError Protocol::UninterceptProtocolInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, const std::string& scheme) { - return static_cast( - request_context_getter->job_factory()) - ->UninterceptProtocol(scheme) + return request_context_getter->job_factory()->UninterceptProtocol(scheme) ? PROTOCOL_OK : PROTOCOL_NOT_INTERCEPTED; } diff --git a/atom/browser/api/atom_api_protocol.h b/atom/browser/api/atom_api_protocol.h index deaf680c996ce..aa1ad98b8e3f7 100644 --- a/atom/browser/api/atom_api_protocol.h +++ b/atom/browser/api/atom_api_protocol.h @@ -100,7 +100,8 @@ class Protocol : public mate::TrackableObject { mate::Arguments* args) { CompletionCallback callback; args->GetNext(&callback); - auto* getter = browser_context_->GetRequestContext(); + auto* getter = static_cast( + browser_context_->GetRequestContext()); content::BrowserThread::PostTaskAndReplyWithResult( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&Protocol::RegisterProtocolInIO, @@ -109,12 +110,11 @@ class Protocol : public mate::TrackableObject { } template static ProtocolError RegisterProtocolInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, v8::Isolate* isolate, const std::string& scheme, const Handler& handler) { - auto* job_factory = static_cast( - request_context_getter->job_factory()); + auto* job_factory = request_context_getter->job_factory(); if (job_factory->IsHandledProtocol(scheme)) return PROTOCOL_REGISTERED; auto protocol_handler = std::make_unique>( @@ -128,14 +128,14 @@ class Protocol : public mate::TrackableObject { // Unregister the protocol handler that handles |scheme|. void UnregisterProtocol(const std::string& scheme, mate::Arguments* args); static ProtocolError UnregisterProtocolInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, const std::string& scheme); // Whether the protocol has handler registered. void IsProtocolHandled(const std::string& scheme, const BooleanCallback& callback); static bool IsProtocolHandledInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, const std::string& scheme); // Replace the protocol handler with a new one. @@ -145,7 +145,8 @@ class Protocol : public mate::TrackableObject { mate::Arguments* args) { CompletionCallback callback; args->GetNext(&callback); - auto* getter = browser_context_->GetRequestContext(); + auto* getter = static_cast( + browser_context_->GetRequestContext()); content::BrowserThread::PostTaskAndReplyWithResult( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&Protocol::InterceptProtocolInIO, @@ -154,12 +155,11 @@ class Protocol : public mate::TrackableObject { } template static ProtocolError InterceptProtocolInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, v8::Isolate* isolate, const std::string& scheme, const Handler& handler) { - auto* job_factory = static_cast( - request_context_getter->job_factory()); + auto* job_factory = request_context_getter->job_factory(); if (!job_factory->IsHandledProtocol(scheme)) return PROTOCOL_NOT_REGISTERED; // It is possible a protocol is handled but can not be intercepted. @@ -175,7 +175,7 @@ class Protocol : public mate::TrackableObject { // Restore the |scheme| to its original protocol handler. void UninterceptProtocol(const std::string& scheme, mate::Arguments* args); static ProtocolError UninterceptProtocolInIO( - scoped_refptr request_context_getter, + scoped_refptr request_context_getter, const std::string& scheme); // Convert error code to JS exception and call the callback. diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 658f913bb60b6..f2d72e846bd22 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -10,6 +10,7 @@ #include "atom/browser/api/atom_api_cookies.h" #include "atom/browser/api/atom_api_download_item.h" +#include "atom/browser/api/atom_api_net_log.h" #include "atom/browser/api/atom_api_protocol.h" #include "atom/browser/api/atom_api_web_request.h" #include "atom/browser/atom_browser_context.h" @@ -29,12 +30,14 @@ #include "base/guid.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "base/threading/thread_task_runner_handle.h" #include "brightray/browser/media/media_device_id_salt.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" #include "components/download/public/common/download_danger_type.h" #include "components/prefs/pref_service.h" +#include "components/prefs/value_map_pref_store.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "components/proxy_config/proxy_config_pref_names.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_item_utils.h" #include "content/public/browser/download_manager_delegate.h" @@ -46,8 +49,8 @@ #include "net/dns/host_cache.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_auth_preferences.h" -#include "net/proxy_resolution/proxy_config_service_fixed.h" -#include "net/proxy_resolution/proxy_service.h" +#include "net/http/http_cache.h" +#include "net/http/http_transaction_factory.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_getter.h" @@ -179,37 +182,6 @@ struct Converter { } }; -template <> -struct Converter { - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - net::ProxyConfig* out) { - std::string proxy_rules, proxy_bypass_rules; - GURL pac_url; - mate::Dictionary options; - // Fallback to previous API when passed String. - // https://git.io/vuhjj - if (ConvertFromV8(isolate, val, &proxy_rules)) { - pac_url = GURL(proxy_rules); // Assume it is PAC script if it is URL. - } else if (ConvertFromV8(isolate, val, &options)) { - options.Get("pacScript", &pac_url); - options.Get("proxyRules", &proxy_rules); - options.Get("proxyBypassRules", &proxy_bypass_rules); - } else { - return false; - } - - // pacScript takes precedence over proxyRules. - if (!pac_url.is_empty() && pac_url.is_valid()) { - out->set_pac_url(pac_url); - } else { - out->proxy_rules().ParseFromString(proxy_rules); - out->proxy_rules().bypass_rules.ParseFromString(proxy_bypass_rules); - } - return true; - } -}; - template <> struct Converter { static v8::Local ToV8(v8::Isolate* isolate, @@ -236,56 +208,6 @@ const char kPersistPrefix[] = "persist:"; // Referenced session objects. std::map> g_sessions; -class ResolveProxyHelper { - public: - ResolveProxyHelper(AtomBrowserContext* browser_context, - const GURL& url, - const Session::ResolveProxyCallback& callback) - : callback_(callback), - original_thread_(base::ThreadTaskRunnerHandle::Get()) { - scoped_refptr context_getter = - browser_context->GetRequestContext(); - context_getter->GetNetworkTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ResolveProxyHelper::ResolveProxy, - base::Unretained(this), context_getter, url)); - } - - void OnResolveProxyCompleted(int result) { - std::string proxy; - if (result == net::OK) - proxy = proxy_info_.ToPacString(); - original_thread_->PostTask(FROM_HERE, base::BindOnce(callback_, proxy)); - delete this; - } - - private: - void ResolveProxy(scoped_refptr context_getter, - const GURL& url) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - net::ProxyResolutionService* proxy_service = - context_getter->GetURLRequestContext()->proxy_resolution_service(); - net::CompletionCallback completion_callback = base::Bind( - &ResolveProxyHelper::OnResolveProxyCompleted, base::Unretained(this)); - - // Start the request. - int result = proxy_service->ResolveProxy(url, "GET", &proxy_info_, - completion_callback, &pac_req_, - nullptr, net::NetLogWithSource()); - - // Completed synchronously. - if (result != net::ERR_IO_PENDING) - completion_callback.Run(result); - } - - Session::ResolveProxyCallback callback_; - net::ProxyInfo proxy_info_; - net::ProxyResolutionService::Request* pac_req_; - scoped_refptr original_thread_; - - DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper); -}; - // Runs the callback in UI thread. void RunCallbackInUI(const base::Callback& callback) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); @@ -343,18 +265,6 @@ void DoCacheActionInIO( on_get_backend.Run(net::OK); } -void SetProxyInIO(scoped_refptr getter, - const net::ProxyConfig& config, - const base::Closure& callback) { - auto* proxy_service = - getter->GetURLRequestContext()->proxy_resolution_service(); - proxy_service->ResetConfigService( - base::WrapUnique(new net::ProxyConfigServiceFixed(config))); - // Refetches and applies the new pac script if provided. - proxy_service->ForceReloadProxyConfig(); - RunCallbackInUI(callback); -} - void SetCertVerifyProcInIO( const scoped_refptr& context_getter, const AtomCertVerifier::VerifyProc& proc) { @@ -442,7 +352,7 @@ void DownloadIdCallback(content::DownloadManager* download_manager, } void SetDevToolsNetworkEmulationClientIdInIO( - brightray::URLRequestContextGetter* url_request_context_getter, + net::URLRequestContextGetter* url_request_context_getter, const std::string& client_id) { if (!url_request_context_getter) return; @@ -491,6 +401,7 @@ Session::~Session() { DestroyGlobalHandle(isolate(), cookies_); DestroyGlobalHandle(isolate(), web_request_); DestroyGlobalHandle(isolate(), protocol_); + DestroyGlobalHandle(isolate(), net_log_); g_sessions.erase(weak_map_id()); } @@ -513,8 +424,10 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, } } -void Session::ResolveProxy(const GURL& url, ResolveProxyCallback callback) { - new ResolveProxyHelper(browser_context(), url, callback); +void Session::ResolveProxy( + const GURL& url, + const ResolveProxyHelper::ResolveProxyCallback& callback) { + browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback); } template @@ -552,13 +465,34 @@ void Session::FlushStorageData() { storage_partition->Flush(); } -void Session::SetProxy(const net::ProxyConfig& config, +void Session::SetProxy(const mate::Dictionary& options, const base::Closure& callback) { - auto* getter = browser_context_->GetRequestContext(); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&SetProxyInIO, base::RetainedRef(getter), config, - callback)); + if (!browser_context_->in_memory_pref_store()) { + callback.Run(); + return; + } + + std::string proxy_rules, bypass_list, pac_url; + + options.Get("pacScript", &pac_url); + options.Get("proxyRules", &proxy_rules); + options.Get("proxyBypassRules", &bypass_list); + + // pacScript takes precedence over proxyRules. + if (!pac_url.empty()) { + browser_context_->in_memory_pref_store()->SetValue( + proxy_config::prefs::kProxy, + ProxyConfigDictionary::CreatePacScript(pac_url, + true /* pac_mandatory */), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + } else { + browser_context_->in_memory_pref_store()->SetValue( + proxy_config::prefs::kProxy, + ProxyConfigDictionary::CreateFixedServers(proxy_rules, bypass_list), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + } + + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); } void Session::SetDownloadPath(const base::FilePath& path) { @@ -669,7 +603,7 @@ void Session::SetUserAgent(const std::string& user_agent, std::string accept_lang = g_browser_process->GetApplicationLocale(); args->GetNext(&accept_lang); - scoped_refptr getter( + scoped_refptr getter( browser_context_->GetRequestContext()); getter->GetNetworkTaskRunner()->PostTask( FROM_HERE, @@ -760,6 +694,14 @@ v8::Local Session::WebRequest(v8::Isolate* isolate) { return v8::Local::New(isolate, web_request_); } +v8::Local Session::NetLog(v8::Isolate* isolate) { + if (net_log_.IsEmpty()) { + auto handle = atom::api::NetLog::Create(isolate, browser_context()); + net_log_.Reset(isolate, handle.ToV8()); + } + return v8::Local::New(isolate, net_log_); +} + // static mate::Handle Session::CreateFrom(v8::Isolate* isolate, AtomBrowserContext* browser_context) { @@ -826,6 +768,7 @@ void Session::BuildPrototype(v8::Isolate* isolate, .SetMethod("setPreloads", &Session::SetPreloads) .SetMethod("getPreloads", &Session::GetPreloads) .SetProperty("cookies", &Session::Cookies) + .SetProperty("netLog", &Session::NetLog) .SetProperty("protocol", &Session::Protocol) .SetProperty("webRequest", &Session::WebRequest); } diff --git a/atom/browser/api/atom_api_session.h b/atom/browser/api/atom_api_session.h index 6c8247c5c4a90..a925a726e2c50 100644 --- a/atom/browser/api/atom_api_session.h +++ b/atom/browser/api/atom_api_session.h @@ -10,6 +10,7 @@ #include "atom/browser/api/trackable_object.h" #include "atom/browser/atom_blob_reader.h" +#include "atom/browser/net/resolve_proxy_helper.h" #include "base/values.h" #include "content/public/browser/download_manager.h" #include "native_mate/handle.h" @@ -39,8 +40,6 @@ namespace api { class Session : public mate::TrackableObject, public content::DownloadManager::Observer { public: - using ResolveProxyCallback = base::Callback; - enum class CacheAction { CLEAR, STATS, @@ -63,12 +62,13 @@ class Session : public mate::TrackableObject, v8::Local prototype); // Methods. - void ResolveProxy(const GURL& url, ResolveProxyCallback callback); + void ResolveProxy(const GURL& url, + const ResolveProxyHelper::ResolveProxyCallback& callback); template void DoCacheAction(const net::CompletionCallback& callback); void ClearStorageData(mate::Arguments* args); void FlushStorageData(); - void SetProxy(const net::ProxyConfig& config, const base::Closure& callback); + void SetProxy(const mate::Dictionary& options, const base::Closure& callback); void SetDownloadPath(const base::FilePath& path); void EnableNetworkEmulation(const mate::Dictionary& options); void DisableNetworkEmulation(); @@ -88,6 +88,7 @@ class Session : public mate::TrackableObject, v8::Local Cookies(v8::Isolate* isolate); v8::Local Protocol(v8::Isolate* isolate); v8::Local WebRequest(v8::Isolate* isolate); + v8::Local NetLog(v8::Isolate* isolate); protected: Session(v8::Isolate* isolate, AtomBrowserContext* browser_context); @@ -102,6 +103,7 @@ class Session : public mate::TrackableObject, v8::Global cookies_; v8::Global protocol_; v8::Global web_request_; + v8::Global net_log_; // The X-DevTools-Emulate-Network-Conditions-Client-Id. std::string devtools_network_emulation_client_id_; diff --git a/atom/browser/api/atom_api_web_request.cc b/atom/browser/api/atom_api_web_request.cc index c088196f83316..aa16094649455 100644 --- a/atom/browser/api/atom_api_web_request.cc +++ b/atom/browser/api/atom_api_web_request.cc @@ -42,7 +42,7 @@ namespace { template void CallNetworkDelegateMethod( - brightray::URLRequestContextGetter* url_request_context_getter, + URLRequestContextGetter* url_request_context_getter, Method method, Event type, URLPatterns patterns, @@ -94,8 +94,8 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) { return; } - brightray::URLRequestContextGetter* url_request_context_getter = - browser_context_->GetRequestContext(); + auto* url_request_context_getter = static_cast( + browser_context_->GetRequestContext()); if (!url_request_context_getter) return; BrowserThread::PostTask( diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index f3bdd884f16ff..acd9a3d4e22ea 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -17,6 +17,7 @@ #include "atom/browser/atom_resource_dispatcher_host_delegate.h" #include "atom/browser/atom_speech_recognition_manager_delegate.h" #include "atom/browser/child_web_contents_tracker.h" +#include "atom/browser/io_thread.h" #include "atom/browser/native_window.h" #include "atom/browser/session_preferences.h" #include "atom/browser/web_contents_permission_helper.h" @@ -27,12 +28,16 @@ #include "base/command_line.h" #include "base/environment.h" #include "base/files/file_util.h" +#include "base/json/json_reader.h" +#include "base/no_destructor.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/printing/printing_message_filter.h" #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" #include "chrome/browser/speech/tts_message_filter.h" +#include "components/net_log/chrome_net_log.h" #include "content/public/browser/browser_ppapi_host.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/render_frame_host.h" @@ -43,12 +48,15 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" +#include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" #include "device/geolocation/public/cpp/location_provider.h" +#include "net/base/escape.h" #include "net/ssl/ssl_cert_request_info.h" #include "ppapi/host/ppapi_host.h" #include "services/network/public/cpp/resource_request_body.h" +#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "v8/include/v8.h" @@ -504,10 +512,28 @@ AtomBrowserClient::OverrideSystemLocationProvider() { #endif } +network::mojom::NetworkContextPtr AtomBrowserClient::CreateNetworkContext( + content::BrowserContext* browser_context, + bool /*in_memory*/, + const base::FilePath& /*relative_partition_path*/) { + if (!browser_context) + return nullptr; + return static_cast(browser_context)->GetNetworkContext(); +} + +void AtomBrowserClient::RegisterOutOfProcessServices( + OutOfProcessServiceMap* services) { + (*services)[proxy_resolver::mojom::kProxyResolverServiceName] = + base::ASCIIToUTF16("V8 Proxy Resolver"); +} + +net::NetLog* AtomBrowserClient::GetNetLog() { + return AtomBrowserMainParts::Get()->net_log(); +} + brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( - const content::MainFunctionParams&) { - v8::V8::Initialize(); // Init V8 before creating main parts. - return new AtomBrowserMainParts; + const content::MainFunctionParams& params) { + return new AtomBrowserMainParts(params); } void AtomBrowserClient::WebNotificationAllowed( diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 95211d72e51f0..53a5f31295a17 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -108,6 +108,12 @@ class AtomBrowserClient : public brightray::BrowserClient, content::ResourceContext* resource_context) override; std::unique_ptr OverrideSystemLocationProvider() override; + network::mojom::NetworkContextPtr CreateNetworkContext( + content::BrowserContext* browser_context, + bool in_memory, + const base::FilePath& relative_partition_path) override; + void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; + net::NetLog* GetNetLog() override; // brightray::BrowserClient: brightray::BrowserMainParts* OverrideCreateBrowserMainParts( diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index ffef00da50a6d..ad5fc61708acd 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -4,12 +4,16 @@ #include "atom/browser/atom_browser_context.h" +#include + #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/request_context_delegate.h" +#include "atom/browser/cookie_change_notifier.h" +#include "atom/browser/net/resolve_proxy_helper.h" +#include "atom/browser/pref_store_delegate.h" #include "atom/browser/web_view_manager.h" #include "atom/common/atom_version.h" #include "atom/common/chrome_version.h" @@ -17,12 +21,31 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/path_service.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "base/threading/thread_restrictions.h" +#include "brightray/browser/brightray_paths.h" +#include "brightray/browser/inspectable_web_contents_impl.h" +#include "brightray/browser/special_storage_policy.h" +#include "brightray/browser/zoom_level_delegate.h" +#include "brightray/common/application_info.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" +#include "components/prefs/json_pref_store.h" #include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/pref_service_factory.h" +#include "components/prefs/value_map_pref_store.h" +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" +#include "components/proxy_config/proxy_config_pref_names.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/user_agent.h" +#include "net/base/escape.h" + +using content::BrowserThread; namespace atom { @@ -36,13 +59,25 @@ std::string RemoveWhitespace(const std::string& str) { return str; } +// Convert string to lower case and escape it. +std::string MakePartitionName(const std::string& input) { + return net::EscapePath(base::ToLowerASCII(input)); +} + } // namespace +// static +AtomBrowserContext::BrowserContextMap AtomBrowserContext::browser_context_map_; + AtomBrowserContext::AtomBrowserContext(const std::string& partition, bool in_memory, const base::DictionaryValue& options) - : brightray::BrowserContext(partition, in_memory), - url_request_context_getter_(nullptr) { + : base::RefCountedDeleteOnSequence( + base::SequencedTaskRunnerHandle::Get()), + in_memory_pref_store_(nullptr), + storage_policy_(new brightray::SpecialStoragePolicy), + in_memory_(in_memory), + weak_factory_(this) { // Construct user agent string. Browser* browser = Browser::Get(); std::string name = RemoveWhitespace(browser->GetName()); @@ -59,23 +94,131 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition, // Read options. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - bool use_cache = !command_line->HasSwitch(switches::kDisableHttpCache); - options.GetBoolean("cache", &use_cache); + use_cache_ = !command_line->HasSwitch(switches::kDisableHttpCache); + options.GetBoolean("cache", &use_cache_); + + base::StringToInt(command_line->GetSwitchValueASCII(switches::kDiskCacheSize), + &max_cache_size_); + + if (!base::PathService::Get(brightray::DIR_USER_DATA, &path_)) { + base::PathService::Get(brightray::DIR_APP_DATA, &path_); + path_ = path_.Append( + base::FilePath::FromUTF8Unsafe(brightray::GetApplicationName())); + base::PathService::Override(brightray::DIR_USER_DATA, path_); + } + + if (!in_memory && !partition.empty()) + path_ = path_.Append(FILE_PATH_LITERAL("Partitions")) + .Append(base::FilePath::FromUTF8Unsafe( + MakePartitionName(partition))); - request_context_delegate_.reset(new RequestContextDelegate(use_cache)); + content::BrowserContext::Initialize(this, path_); - // Initialize Pref Registry in brightray. + // Initialize Pref Registry. InitPrefs(); + + proxy_config_monitor_ = std::make_unique(prefs_.get()); + io_handle_ = new URLRequestContextGetter::Handle(weak_factory_.GetWeakPtr()); + cookie_change_notifier_ = std::make_unique(this); } AtomBrowserContext::~AtomBrowserContext() { - url_request_context_getter_->set_delegate(nullptr); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + NotifyWillBeDestroyed(this); + ShutdownStoragePartitions(); + io_handle_->ShutdownOnUIThread(); +} + +void AtomBrowserContext::InitPrefs() { + auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences")); + base::ThreadRestrictions::ScopedAllowIO allow_io; + PrefServiceFactory prefs_factory; + scoped_refptr pref_store = + base::MakeRefCounted(prefs_path); + pref_store->ReadPrefs(); // Synchronous. + prefs_factory.set_user_prefs(pref_store); + + auto registry = WrapRefCounted(new PrefRegistrySimple); + + registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, + base::FilePath()); + base::FilePath download_dir; + base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir); + registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory, + download_dir); + registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); + brightray::InspectableWebContentsImpl::RegisterPrefs(registry.get()); + brightray::MediaDeviceIDSalt::RegisterPrefs(registry.get()); + brightray::ZoomLevelDelegate::RegisterPrefs(registry.get()); + PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get()); + + prefs_ = prefs_factory.Create( + registry.get(), + std::make_unique(weak_factory_.GetWeakPtr())); + prefs_->UpdateCommandLinePrefStore(new ValueMapPrefStore); } void AtomBrowserContext::SetUserAgent(const std::string& user_agent) { user_agent_ = user_agent; } +net::URLRequestContextGetter* AtomBrowserContext::CreateRequestContext( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector protocol_interceptors) { + return io_handle_ + ->CreateMainRequestContextGetter(protocol_handlers, + std::move(protocol_interceptors)) + .get(); +} + +net::URLRequestContextGetter* AtomBrowserContext::CreateMediaRequestContext() { + return io_handle_->GetMainRequestContextGetter().get(); +} + +net::URLRequestContextGetter* AtomBrowserContext::GetRequestContext() { + return GetDefaultStoragePartition(this)->GetURLRequestContext(); +} + +network::mojom::NetworkContextPtr AtomBrowserContext::GetNetworkContext() { + return io_handle_->GetNetworkContext(); +} + +base::FilePath AtomBrowserContext::GetPath() const { + return path_; +} + +bool AtomBrowserContext::IsOffTheRecord() const { + return in_memory_; +} + +bool AtomBrowserContext::CanUseHttpCache() const { + return use_cache_; +} + +int AtomBrowserContext::GetMaxCacheSize() const { + return max_cache_size_; +} + +content::ResourceContext* AtomBrowserContext::GetResourceContext() { + return io_handle_->GetResourceContext(); +} + +std::string AtomBrowserContext::GetMediaDeviceIDSalt() { + if (!media_device_id_salt_.get()) + media_device_id_salt_.reset(new brightray::MediaDeviceIDSalt(prefs_.get())); + return media_device_id_salt_->GetSalt(); +} + +std::unique_ptr +AtomBrowserContext::CreateZoomLevelDelegate( + const base::FilePath& partition_path) { + if (!IsOffTheRecord()) { + return std::make_unique(prefs(), + partition_path); + } + return std::unique_ptr(); +} + content::DownloadManagerDelegate* AtomBrowserContext::GetDownloadManagerDelegate() { if (!download_manager_delegate_.get()) { @@ -98,26 +241,14 @@ content::PermissionManager* AtomBrowserContext::GetPermissionManager() { return permission_manager_.get(); } -void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) { - pref_registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory, - base::FilePath()); - base::FilePath download_dir; - PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &download_dir); - pref_registry->RegisterFilePathPref(prefs::kDownloadDefaultDirectory, - download_dir); - pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths); +storage::SpecialStoragePolicy* AtomBrowserContext::GetSpecialStoragePolicy() { + return storage_policy_.get(); } 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 = @@ -127,16 +258,67 @@ AtomBlobReader* AtomBrowserContext::GetBlobReader() { return blob_reader_.get(); } +content::PushMessagingService* AtomBrowserContext::GetPushMessagingService() { + return nullptr; +} + +content::SSLHostStateDelegate* AtomBrowserContext::GetSSLHostStateDelegate() { + return nullptr; +} + +content::BackgroundFetchDelegate* +AtomBrowserContext::GetBackgroundFetchDelegate() { + return nullptr; +} + +content::BackgroundSyncController* +AtomBrowserContext::GetBackgroundSyncController() { + return nullptr; +} + +content::BrowsingDataRemoverDelegate* +AtomBrowserContext::GetBrowsingDataRemoverDelegate() { + return nullptr; +} + +net::URLRequestContextGetter* +AtomBrowserContext::CreateRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) { + NOTREACHED(); + return nullptr; +} + +net::URLRequestContextGetter* +AtomBrowserContext::CreateMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) { + NOTREACHED(); + return nullptr; +} + +ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() { + if (!resolve_proxy_helper_) { + resolve_proxy_helper_ = base::MakeRefCounted(this); + } + return resolve_proxy_helper_.get(); +} + // static scoped_refptr AtomBrowserContext::From( const std::string& partition, bool in_memory, const base::DictionaryValue& options) { - auto browser_context = brightray::BrowserContext::Get(partition, in_memory); + PartitionKey key(partition, in_memory); + auto* browser_context = browser_context_map_[key].get(); if (browser_context) - return static_cast(browser_context.get()); + return scoped_refptr(browser_context); - return new AtomBrowserContext(partition, in_memory, options); + auto* new_context = new AtomBrowserContext(partition, in_memory, options); + browser_context_map_[key] = new_context->GetWeakPtr(); + return scoped_refptr(new_context); } } // namespace atom diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 581ecc185f122..db777f2e78d39 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -5,20 +5,39 @@ #ifndef ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_ #define ATOM_BROWSER_ATOM_BROWSER_CONTEXT_H_ +#include +#include #include #include -#include "brightray/browser/browser_context.h" +#include "atom/browser/net/url_request_context_getter.h" +#include "base/memory/ref_counted_delete_on_sequence.h" +#include "base/memory/weak_ptr.h" +#include "brightray/browser/media/media_device_id_salt.h" +#include "chrome/browser/net/proxy_config_monitor.h" +#include "content/public/browser/browser_context.h" + +class PrefRegistrySimple; +class PrefService; +class ValueMapPrefStore; + +namespace brightray { +class SpecialStoragePolicy; +} namespace atom { class AtomBlobReader; +class AtomBrowserContext; class AtomDownloadManagerDelegate; class AtomPermissionManager; -class RequestContextDelegate; +class CookieChangeNotifier; +class ResolveProxyHelper; class WebViewManager; -class AtomBrowserContext : public brightray::BrowserContext { +class AtomBrowserContext + : public base::RefCountedDeleteOnSequence, + public content::BrowserContext { public: // Get or create the BrowserContext according to its |partition| and // |in_memory|. The |options| will be passed to constructor when there is no @@ -29,21 +48,60 @@ class AtomBrowserContext : public brightray::BrowserContext { const base::DictionaryValue& options = base::DictionaryValue()); void SetUserAgent(const std::string& user_agent); + std::string GetUserAgent() const; + bool CanUseHttpCache() const; + int GetMaxCacheSize() const; AtomBlobReader* GetBlobReader(); + network::mojom::NetworkContextPtr GetNetworkContext(); + // Get the request context, if there is none, create it. + net::URLRequestContextGetter* GetRequestContext(); + ResolveProxyHelper* GetResolveProxyHelper(); // content::BrowserContext: + base::FilePath GetPath() const override; + bool IsOffTheRecord() const override; + content::ResourceContext* GetResourceContext() override; + std::unique_ptr CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + content::PushMessagingService* GetPushMessagingService() override; + content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; + content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override; + content::BackgroundSyncController* GetBackgroundSyncController() override; + content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate() + override; + net::URLRequestContextGetter* CreateRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) override; + net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition( + const base::FilePath& partition_path, + bool in_memory) override; + std::string GetMediaDeviceIDSalt() override; content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; content::BrowserPluginGuestManager* GetGuestManager() override; content::PermissionManager* GetPermissionManager() override; - - // brightray::BrowserContext: - void RegisterPrefs(PrefRegistrySimple* pref_registry) override; - std::string GetUserAgent() const override; - void OnMainRequestContextCreated( - brightray::URLRequestContextGetter* getter) override; - - RequestContextDelegate* GetRequestContextDelegate() const { - return request_context_delegate_.get(); + storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; + net::URLRequestContextGetter* CreateRequestContext( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector request_interceptors) override; + net::URLRequestContextGetter* CreateMediaRequestContext() override; + + CookieChangeNotifier* cookie_change_notifier() const { + return cookie_change_notifier_.get(); + } + ProxyConfigMonitor* proxy_config_monitor() { + return proxy_config_monitor_.get(); + } + PrefService* prefs() const { return prefs_.get(); } + void set_in_memory_pref_store(ValueMapPrefStore* pref_store) { + in_memory_pref_store_ = pref_store; + } + ValueMapPrefStore* in_memory_pref_store() const { + return in_memory_pref_store_; + } + base::WeakPtr GetWeakPtr() { + return weak_factory_.GetWeakPtr(); } protected: @@ -53,14 +111,60 @@ class AtomBrowserContext : public brightray::BrowserContext { ~AtomBrowserContext() override; private: - brightray::URLRequestContextGetter* url_request_context_getter_; - + friend class base::RefCountedDeleteOnSequence; + friend class base::DeleteHelper; + + // Initialize pref registry. + void InitPrefs(); + + // partition_id => browser_context + struct PartitionKey { + std::string partition; + bool in_memory; + + PartitionKey(const std::string& partition, bool in_memory) + : partition(partition), in_memory(in_memory) {} + + bool operator<(const PartitionKey& other) const { + if (partition == other.partition) + return in_memory < other.in_memory; + return partition < other.partition; + } + + bool operator==(const PartitionKey& other) const { + return (partition == other.partition) && (in_memory == other.in_memory); + } + }; + using BrowserContextMap = + std::map>; + static BrowserContextMap browser_context_map_; + + // Self-destructing class responsible for creating URLRequestContextGetter + // on the UI thread and deletes itself on the IO thread. + URLRequestContextGetter::Handle* io_handle_; + ValueMapPrefStore* in_memory_pref_store_; + + std::unique_ptr cookie_change_notifier_; + std::unique_ptr prefs_; 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::unique_ptr media_device_id_salt_; + scoped_refptr resolve_proxy_helper_; + scoped_refptr storage_policy_; + + // Tracks the ProxyConfig to use, and passes any updates to a NetworkContext + // ProxyConfigClient. + std::unique_ptr proxy_config_monitor_; + std::string user_agent_; + base::FilePath path_; + bool in_memory_ = false; + bool use_cache_ = true; + int max_cache_size_ = 0; + + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext); }; diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index cb32a92302a9f..4096f43bae676 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -10,6 +10,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/bridge_task_runner.h" #include "atom/browser/browser.h" +#include "atom/browser/io_thread.h" #include "atom/browser/javascript_environment.h" #include "atom/browser/node_debugger.h" #include "atom/common/api/atom_bindings.h" @@ -18,10 +19,15 @@ #include "base/command_line.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/net/chrome_net_log_helper.h" +#include "components/net_log/chrome_net_log.h" +#include "components/net_log/net_export_file_writer.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/common/result_codes.h" #include "content/public/common/service_manager_connection.h" #include "services/device/public/mojom/constants.mojom.h" +#include "services/network/public/cpp/network_switches.h" #include "services/service_manager/public/cpp/connector.h" #include "ui/base/idle/idle.h" #include "ui/base/l10n/l10n_util.h" @@ -58,12 +64,14 @@ void Erase(T* container, typename T::iterator iter) { // static AtomBrowserMainParts* AtomBrowserMainParts::self_ = nullptr; -AtomBrowserMainParts::AtomBrowserMainParts() +AtomBrowserMainParts::AtomBrowserMainParts( + const content::MainFunctionParams& params) : fake_browser_process_(new BrowserProcess), browser_(new Browser), node_bindings_(NodeBindings::Create(NodeBindings::BROWSER)), atom_bindings_(new AtomBindings(uv_default_loop())), - gc_timer_(true, true) { + gc_timer_(true, true), + main_function_params_(params) { DCHECK(!self_) << "Cannot have two AtomBrowserMainParts"; self_ = this; // Register extension scheme as web safe scheme. @@ -175,9 +183,34 @@ int AtomBrowserMainParts::PreCreateThreads() { ui::InitIdleMonitor(); #endif + net_log_ = std::make_unique(); + auto& command_line = main_function_params_.command_line; + // start net log trace if --log-net-log is passed in the command line. + if (command_line.HasSwitch(network::switches::kLogNetLog)) { + base::FilePath log_file = + command_line.GetSwitchValuePath(network::switches::kLogNetLog); + if (!log_file.empty()) { + net_log_->StartWritingToFile( + log_file, GetNetCaptureModeFromCommandLine(command_line), + command_line.GetCommandLineString(), std::string()); + } + } + // Initialize net log file exporter. + net_log_->net_export_file_writer()->Initialize( + content::BrowserThread::GetTaskRunnerForThread( + content::BrowserThread::IO)); + + // Manage global state of net and other IO thread related. + io_thread_ = std::make_unique(net_log_.get()); + return result; } +void AtomBrowserMainParts::PostDestroyThreads() { + brightray::BrowserMainParts::PostDestroyThreads(); + io_thread_.reset(); +} + void AtomBrowserMainParts::ToolkitInitialized() { brightray::BrowserMainParts::ToolkitInitialized(); #if defined(OS_MACOSX) diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index c6ea9b5a5f72e..7688b2fe7e8ec 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -12,6 +12,7 @@ #include "base/timer/timer.h" #include "brightray/browser/browser_main_parts.h" #include "content/public/browser/browser_context.h" +#include "content/public/common/main_function_params.h" #include "services/device/public/mojom/geolocation_control.mojom.h" class BrowserProcess; @@ -22,10 +23,15 @@ class ViewsDelegate; } #endif +namespace net_log { +class ChromeNetLog; +} + namespace atom { class AtomBindings; class Browser; +class IOThread; class JavascriptEnvironment; class NodeBindings; class NodeDebugger; @@ -38,7 +44,7 @@ class ViewsDelegateMac; class AtomBrowserMainParts : public brightray::BrowserMainParts { public: - AtomBrowserMainParts(); + explicit AtomBrowserMainParts(const content::MainFunctionParams& params); ~AtomBrowserMainParts() override; static AtomBrowserMainParts* Get(); @@ -59,6 +65,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { device::mojom::GeolocationControl* GetGeolocationControl(); Browser* browser() { return browser_.get(); } + IOThread* io_thread() const { return io_thread_.get(); } + net_log::ChromeNetLog* net_log() { return net_log_.get(); } protected: // content::BrowserMainParts: @@ -73,6 +81,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { #if defined(OS_MACOSX) void PreMainMessageLoopStart() override; #endif + void PostDestroyThreads() override; private: #if defined(OS_POSIX) @@ -107,6 +116,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { std::unique_ptr atom_bindings_; std::unique_ptr node_env_; std::unique_ptr node_debugger_; + std::unique_ptr io_thread_; + std::unique_ptr net_log_; base::Timer gc_timer_; @@ -115,6 +126,8 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { device::mojom::GeolocationControlPtr geolocation_control_; + const content::MainFunctionParams main_function_params_; + static AtomBrowserMainParts* self_; DISALLOW_COPY_AND_ASSIGN(AtomBrowserMainParts); diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index b3b1195e044cd..53503d56383e7 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -166,8 +166,8 @@ void CommonWebContentsDelegate::InitWithWebContents( !web_preferences || web_preferences->IsEnabled(options::kOffscreen); // Create InspectableWebContents. - web_contents_.reset( - brightray::InspectableWebContents::Create(web_contents, is_guest)); + web_contents_.reset(brightray::InspectableWebContents::Create( + web_contents, browser_context->prefs(), is_guest)); web_contents_->SetDelegate(this); } @@ -194,8 +194,17 @@ void CommonWebContentsDelegate::SetOwnerWindow( void CommonWebContentsDelegate::ResetManagedWebContents(bool async) { if (async) { - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, - web_contents_.release()); + // Browser context should be destroyed only after the WebContents, + // this is guaranteed in the sync mode by the order of declaration, + // in the async version we maintain a reference until the WebContents + // is destroyed. + base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask( + FROM_HERE, + base::BindOnce([](scoped_refptr browser_context, + std::unique_ptr + web_contents) { web_contents.reset(); }, + base::RetainedRef(browser_context_), + std::move(web_contents_))); } else { web_contents_.reset(); } diff --git a/atom/browser/cookie_change_notifier.cc b/atom/browser/cookie_change_notifier.cc new file mode 100644 index 0000000000000..a0f99d2779d55 --- /dev/null +++ b/atom/browser/cookie_change_notifier.cc @@ -0,0 +1,72 @@ +// 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/cookie_change_notifier.h" + +#include + +#include "atom/browser/atom_browser_context.h" +#include "atom/browser/net/cookie_details.h" +#include "base/bind.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "net/cookies/canonical_cookie.h" + +using content::BrowserThread; + +namespace atom { + +CookieChangeNotifier::CookieChangeNotifier(AtomBrowserContext* browser_context) + : browser_context_(browser_context), binding_(this) { + StartListening(); +} + +CookieChangeNotifier::~CookieChangeNotifier() = default; + +std::unique_ptr::Subscription> +CookieChangeNotifier::RegisterCookieChangeCallback( + const base::Callback& cb) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + return cookie_change_sub_list_.Add(cb); +} + +void CookieChangeNotifier::StartListening() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!binding_.is_bound()); + + network::mojom::CookieManager* cookie_manager = + content::BrowserContext::GetDefaultStoragePartition(browser_context_) + ->GetCookieManagerForBrowserProcess(); + // Cookie manager should be created whenever network context is created, + // if this fails then there is something wrong with our context creation + // cycle. + CHECK(cookie_manager); + + network::mojom::CookieChangeListenerPtr listener_ptr; + binding_.Bind(mojo::MakeRequest(&listener_ptr)); + binding_.set_connection_error_handler(base::BindOnce( + &CookieChangeNotifier::OnConnectionError, base::Unretained(this))); + + cookie_manager->AddGlobalChangeListener(std::move(listener_ptr)); +} + +void CookieChangeNotifier::OnConnectionError() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + binding_.Close(); + StartListening(); +} + +void CookieChangeNotifier::OnCookieChange( + const net::CanonicalCookie& cookie, + network::mojom::CookieChangeCause cause) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + CookieDetails cookie_details( + &cookie, cause != network::mojom::CookieChangeCause::INSERTED, cause); + cookie_change_sub_list_.Notify(&cookie_details); +} + +} // namespace atom diff --git a/atom/browser/cookie_change_notifier.h b/atom/browser/cookie_change_notifier.h new file mode 100644 index 0000000000000..49a0ea50bf97c --- /dev/null +++ b/atom/browser/cookie_change_notifier.h @@ -0,0 +1,48 @@ +// 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_COOKIE_CHANGE_NOTIFIER_H_ +#define ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_ + +#include + +#include "base/callback_list.h" +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" + +namespace atom { + +class AtomBrowserContext; +struct CookieDetails; + +// Sends cookie-change notifications on the UI thread. +class CookieChangeNotifier : public network::mojom::CookieChangeListener { + public: + explicit CookieChangeNotifier(AtomBrowserContext* browser_context); + ~CookieChangeNotifier() override; + + // Register callbacks that needs to notified on any cookie store changes. + std::unique_ptr::Subscription> + RegisterCookieChangeCallback( + const base::Callback& cb); + + private: + void StartListening(); + void OnConnectionError(); + + // network::mojom::CookieChangeListener implementation. + void OnCookieChange(const net::CanonicalCookie& cookie, + network::mojom::CookieChangeCause cause) override; + + AtomBrowserContext* browser_context_; + base::CallbackList cookie_change_sub_list_; + mojo::Binding binding_; + + DISALLOW_COPY_AND_ASSIGN(CookieChangeNotifier); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_COOKIE_CHANGE_NOTIFIER_H_ diff --git a/atom/browser/io_thread.cc b/atom/browser/io_thread.cc new file mode 100644 index 0000000000000..e01f9f28904a8 --- /dev/null +++ b/atom/browser/io_thread.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/io_thread.h" + +#include "components/net_log/chrome_net_log.h" +#include "content/public/browser/browser_thread.h" +#include "net/proxy_resolution/proxy_service.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" + +#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; + +namespace atom { + +IOThread::IOThread(net_log::ChromeNetLog* net_log) : net_log_(net_log) { + BrowserThread::SetIOThreadDelegate(this); +} + +IOThread::~IOThread() { + BrowserThread::SetIOThreadDelegate(nullptr); +} + +void IOThread::Init() { + net::URLRequestContextBuilder builder; + // TODO(deepak1556): We need to respoect user proxy configurations, + // the following initialization has to happen before any request + // contexts are utilized by the io thread, so that proper cert validation + // take place, solutions: + // 1) Use the request context from default partition, but since + // an app can completely run on a custom session without ever creating + // 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() { +#if defined(USE_NSS_CERTS) + 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_) + net_log_->ShutDownBeforeTaskScheduler(); +} + +} // namespace atom diff --git a/brightray/browser/io_thread.h b/atom/browser/io_thread.h similarity index 55% rename from brightray/browser/io_thread.h rename to atom/browser/io_thread.h index b7ddae0eb7e80..4e1027e4ca8ec 100644 --- a/brightray/browser/io_thread.h +++ b/atom/browser/io_thread.h @@ -2,12 +2,13 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef BRIGHTRAY_BROWSER_IO_THREAD_H_ -#define BRIGHTRAY_BROWSER_IO_THREAD_H_ +#ifndef ATOM_BROWSER_IO_THREAD_H_ +#define ATOM_BROWSER_IO_THREAD_H_ #include #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "content/public/browser/browser_thread_delegate.h" namespace net { @@ -15,15 +16,19 @@ class URLRequestContext; class URLRequestContextGetter; } // namespace net -namespace brightray { +namespace net_log { +class ChromeNetLog; +} + +namespace atom { class IOThread : public content::BrowserThreadDelegate { public: - IOThread(); + explicit IOThread(net_log::ChromeNetLog* net_log); ~IOThread() override; net::URLRequestContextGetter* GetRequestContext() { - return url_request_context_getter_; + return url_request_context_getter_.get(); } protected: @@ -32,12 +37,15 @@ class IOThread : public content::BrowserThreadDelegate { void CleanUp() override; private: + // The NetLog is owned by the browser process, to allow logging from other + // threads during shutdown, but is used most frequently on the IOThread. + net_log::ChromeNetLog* net_log_; std::unique_ptr url_request_context_; - net::URLRequestContextGetter* url_request_context_getter_; + scoped_refptr url_request_context_getter_; DISALLOW_COPY_AND_ASSIGN(IOThread); }; -} // namespace brightray +} // namespace atom -#endif // BRIGHTRAY_BROWSER_IO_THREAD_H_ +#endif // ATOM_BROWSER_IO_THREAD_H_ diff --git a/atom/browser/net/atom_url_request.cc b/atom/browser/net/atom_url_request.cc index 5ffbfd65a48b4..90b3ee5b7c396 100644 --- a/atom/browser/net/atom_url_request.cc +++ b/atom/browser/net/atom_url_request.cc @@ -69,7 +69,7 @@ scoped_refptr AtomURLRequest::Create( if (!browser_context || url.empty() || !delegate) { return nullptr; } - scoped_refptr request_context_getter( + scoped_refptr request_context_getter( browser_context->GetRequestContext()); DCHECK(request_context_getter); scoped_refptr atom_url_request(new AtomURLRequest(delegate)); diff --git a/atom/browser/net/atom_url_request_job_factory.cc b/atom/browser/net/atom_url_request_job_factory.cc index 7047f7a6f7f83..fd4f3a8377f0f 100644 --- a/atom/browser/net/atom_url_request_job_factory.cc +++ b/atom/browser/net/atom_url_request_job_factory.cc @@ -5,6 +5,8 @@ #include "atom/browser/net/atom_url_request_job_factory.h" +#include + #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "content/public/browser/browser_thread.h" @@ -33,6 +35,11 @@ AtomURLRequestJobFactory::~AtomURLRequestJobFactory() { Clear(); } +void AtomURLRequestJobFactory::Chain( + std::unique_ptr job_factory) { + job_factory_ = std::move(job_factory); +} + bool AtomURLRequestJobFactory::SetProtocolHandler( const std::string& scheme, std::unique_ptr protocol_handler) { @@ -73,16 +80,6 @@ bool AtomURLRequestJobFactory::UninterceptProtocol(const std::string& scheme) { return true; } -ProtocolHandler* AtomURLRequestJobFactory::GetProtocolHandler( - const std::string& scheme) const { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - - auto it = protocol_handler_map_.find(scheme); - if (it == protocol_handler_map_.end()) - return nullptr; - return it->second; -} - bool AtomURLRequestJobFactory::HasProtocolHandler( const std::string& scheme) const { return base::ContainsKey(protocol_handler_map_, scheme); @@ -101,11 +98,18 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( net::NetworkDelegate* network_delegate) const { DCHECK_CURRENTLY_ON(BrowserThread::IO); + auto* job = job_factory_->MaybeCreateJobWithProtocolHandler(scheme, request, + network_delegate); + if (job) + return job; + auto it = protocol_handler_map_.find(scheme); if (it == protocol_handler_map_.end()) return nullptr; + if (request->GetUserData(DisableProtocolInterceptFlagKey())) return nullptr; + return it->second->MaybeCreateJob(request, network_delegate); } @@ -113,13 +117,14 @@ net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptRedirect( net::URLRequest* request, net::NetworkDelegate* network_delegate, const GURL& location) const { - return nullptr; + return job_factory_->MaybeInterceptRedirect(request, network_delegate, + location); } net::URLRequestJob* AtomURLRequestJobFactory::MaybeInterceptResponse( net::URLRequest* request, net::NetworkDelegate* network_delegate) const { - return nullptr; + return job_factory_->MaybeInterceptResponse(request, network_delegate); } bool AtomURLRequestJobFactory::IsHandledProtocol( diff --git a/atom/browser/net/atom_url_request_job_factory.h b/atom/browser/net/atom_url_request_job_factory.h index c0e26568fdea5..fe965e237be09 100644 --- a/atom/browser/net/atom_url_request_job_factory.h +++ b/atom/browser/net/atom_url_request_job_factory.h @@ -23,6 +23,9 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory { AtomURLRequestJobFactory(); ~AtomURLRequestJobFactory() override; + // Requests are forwarded to the chained job factory first. + void Chain(std::unique_ptr job_factory); + // Sets the ProtocolHandler for a scheme. Returns true on success, false on // failure (a ProtocolHandler already exists for |scheme|). On success, // URLRequestJobFactory takes ownership of |protocol_handler|. @@ -34,9 +37,6 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory { std::unique_ptr protocol_handler); bool UninterceptProtocol(const std::string& scheme); - // Returns the protocol handler registered with scheme. - ProtocolHandler* GetProtocolHandler(const std::string& scheme) const; - // Whether the protocol handler is registered by the job factory. bool HasProtocolHandler(const std::string& scheme) const; @@ -69,6 +69,8 @@ class AtomURLRequestJobFactory : public net::URLRequestJobFactory { // Can only be accessed in IO thread. OriginalProtocolsMap original_protocols_; + std::unique_ptr job_factory_; + DISALLOW_COPY_AND_ASSIGN(AtomURLRequestJobFactory); }; diff --git a/atom/browser/net/cookie_details.h b/atom/browser/net/cookie_details.h index 9e361f199c6c1..82ad8d6f7aa15 100644 --- a/atom/browser/net/cookie_details.h +++ b/atom/browser/net/cookie_details.h @@ -6,7 +6,11 @@ #define ATOM_BROWSER_NET_COOKIE_DETAILS_H_ #include "base/macros.h" -#include "net/cookies/cookie_change_dispatcher.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" + +namespace net { +class CanonicalCookie; +} namespace atom { @@ -14,12 +18,12 @@ struct CookieDetails { public: CookieDetails(const net::CanonicalCookie* cookie_copy, bool is_removed, - net::CookieChangeCause cause) + network::mojom::CookieChangeCause cause) : cookie(cookie_copy), removed(is_removed), cause(cause) {} const net::CanonicalCookie* cookie; bool removed; - net::CookieChangeCause cause; + network::mojom::CookieChangeCause cause; }; } // namespace atom diff --git a/atom/browser/net/resolve_proxy_helper.cc b/atom/browser/net/resolve_proxy_helper.cc new file mode 100644 index 0000000000000..51767418bdc40 --- /dev/null +++ b/atom/browser/net/resolve_proxy_helper.cc @@ -0,0 +1,87 @@ +// 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/net/resolve_proxy_helper.h" + +#include "atom/browser/atom_browser_context.h" +#include "base/bind.h" +#include "base/threading/thread_task_runner_handle.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" + +namespace atom { + +ResolveProxyHelper::ResolveProxyHelper(AtomBrowserContext* browser_context) + : context_getter_(browser_context->GetRequestContext()), + original_thread_(base::ThreadTaskRunnerHandle::Get()) {} + +ResolveProxyHelper::~ResolveProxyHelper() { + // Clear all pending requests if the ProxyService is still alive. + pending_requests_.clear(); +} + +void ResolveProxyHelper::ResolveProxy(const GURL& url, + const ResolveProxyCallback& callback) { + // Enqueue the pending request. + pending_requests_.push_back(PendingRequest(url, callback)); + + // If nothing is in progress, start. + if (pending_requests_.size() == 1) + StartPendingRequest(); +} + +void ResolveProxyHelper::StartPendingRequest() { + auto& pending_request = pending_requests_.front(); + context_getter_->GetNetworkTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&ResolveProxyHelper::StartPendingRequestInIO, + base::Unretained(this), pending_request.url)); +} + +void ResolveProxyHelper::StartPendingRequestInIO(const GURL& url) { + auto* proxy_service = + context_getter_->GetURLRequestContext()->proxy_resolution_service(); + // Start the request. + int result = proxy_service->ResolveProxy( + url, std::string(), &proxy_info_, + base::Bind(&ResolveProxyHelper::OnProxyResolveComplete, + base::RetainedRef(this)), + nullptr, nullptr, net::NetLogWithSource()); + // Completed synchronously. + if (result != net::ERR_IO_PENDING) + OnProxyResolveComplete(result); +} + +void ResolveProxyHelper::OnProxyResolveComplete(int result) { + DCHECK(!pending_requests_.empty()); + + std::string proxy; + if (result == net::OK) + proxy = proxy_info_.ToPacString(); + + original_thread_->PostTask( + FROM_HERE, base::BindOnce(&ResolveProxyHelper::SendProxyResult, + base::RetainedRef(this), proxy)); +} + +void ResolveProxyHelper::SendProxyResult(const std::string& proxy) { + DCHECK(!pending_requests_.empty()); + + const auto& completed_request = pending_requests_.front(); + if (!completed_request.callback.is_null()) + completed_request.callback.Run(proxy); + + // Clear the current (completed) request. + pending_requests_.pop_front(); + + // Start the next request. + if (!pending_requests_.empty()) + StartPendingRequest(); +} + +ResolveProxyHelper::PendingRequest::PendingRequest( + const GURL& url, + const ResolveProxyCallback& callback) + : url(url), callback(callback) {} + +} // namespace atom diff --git a/atom/browser/net/resolve_proxy_helper.h b/atom/browser/net/resolve_proxy_helper.h new file mode 100644 index 0000000000000..45cd3374262aa --- /dev/null +++ b/atom/browser/net/resolve_proxy_helper.h @@ -0,0 +1,61 @@ +// 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_NET_RESOLVE_PROXY_HELPER_H_ +#define ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ + +#include +#include + +#include "base/memory/ref_counted.h" +#include "net/proxy_resolution/proxy_service.h" +#include "url/gurl.h" + +namespace net { +class URLRequestContextGetter; +} + +namespace atom { + +class AtomBrowserContext; + +class ResolveProxyHelper + : public base::RefCountedThreadSafe { + public: + using ResolveProxyCallback = base::Callback; + + explicit ResolveProxyHelper(AtomBrowserContext* browser_context); + + void ResolveProxy(const GURL& url, const ResolveProxyCallback& callback); + + private: + friend class base::RefCountedThreadSafe; + // A PendingRequest is a resolve request that is in progress, or queued. + struct PendingRequest { + public: + PendingRequest(const GURL& url, const ResolveProxyCallback& callback); + + GURL url; + ResolveProxyCallback callback; + }; + + ~ResolveProxyHelper(); + + // Starts the first pending request. + void StartPendingRequest(); + void StartPendingRequestInIO(const GURL& url); + void OnProxyResolveComplete(int result); + void SendProxyResult(const std::string& proxy); + + net::ProxyInfo proxy_info_; + std::deque pending_requests_; + scoped_refptr context_getter_; + scoped_refptr original_thread_; + + DISALLOW_COPY_AND_ASSIGN(ResolveProxyHelper); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_RESOLVE_PROXY_HELPER_H_ diff --git a/atom/browser/net/url_request_context_getter.cc b/atom/browser/net/url_request_context_getter.cc new file mode 100644 index 0000000000000..234e1901c59fd --- /dev/null +++ b/atom/browser/net/url_request_context_getter.cc @@ -0,0 +1,413 @@ +// 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/net/url_request_context_getter.h" + +#include +#include +#include + +#include "atom/browser/api/atom_api_protocol.h" +#include "atom/browser/atom_browser_client.h" +#include "atom/browser/atom_browser_context.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/http_protocol_handler.h" +#include "atom/common/options_switches.h" +#include "base/command_line.h" +#include "base/strings/string_util.h" +#include "base/task_scheduler/post_task.h" +#include "brightray/browser/net/require_ct_delegate.h" +#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "components/prefs/value_map_pref_store.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "components/proxy_config/proxy_config_pref_names.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/devtools_network_transaction_factory.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/resource_context.h" +#include "content/public/common/content_switches.h" +#include "net/base/host_mapping_rules.h" +#include "net/cert/multi_log_ct_verifier.h" +#include "net/cookies/cookie_monster.h" +#include "net/dns/mapped_host_resolver.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_auth_preferences.h" +#include "net/http/http_auth_scheme.h" +#include "net/http/http_transaction_factory.h" +#include "net/log/net_log.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/traffic_annotation/network_traffic_annotation.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/static_http_user_agent_settings.h" +#include "net/url_request/url_request_intercepting_job_factory.h" +#include "net/url_request/url_request_job_factory_impl.h" +#include "services/network/ignore_errors_cert_verifier.h" +#include "services/network/network_service.h" +#include "services/network/public/cpp/network_switches.h" +#include "services/network/url_request_context_builder_mojo.h" +#include "url/url_constants.h" + +#if !BUILDFLAG(DISABLE_FTP_SUPPORT) +#include "net/url_request/ftp_protocol_handler.h" +#endif + +using content::BrowserThread; + +namespace atom { + +namespace { + +network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams( + const base::FilePath& base_path, + const std::string& user_agent, + bool in_memory, + bool use_cache, + int max_cache_size) { + network::mojom::NetworkContextParamsPtr network_context_params = + network::mojom::NetworkContextParams::New(); + network_context_params->enable_brotli = true; + network_context_params->user_agent = user_agent; + network_context_params->http_cache_enabled = use_cache; + network_context_params->enable_data_url_support = false; + network_context_params->proxy_resolver_factory = + ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface(); + if (!in_memory) { + network_context_params->http_cache_path = + base_path.Append(chrome::kCacheDirname); + network_context_params->http_cache_max_size = max_cache_size; + network_context_params->http_server_properties_path = + base_path.Append(chrome::kNetworkPersistentStateFilename); + network_context_params->cookie_path = + base_path.Append(chrome::kCookieFilename); + network_context_params->channel_id_path = + base_path.Append(chrome::kChannelIDFilename); + network_context_params->restore_old_session_cookies = false; + network_context_params->persist_session_cookies = false; + } + // TODO(deepak1556): Decide the stand on chrome ct policy and + // enable it. + // See //net/docs/certificate-transparency.md + // network_context_params->enforce_chrome_ct_policy = true; + return network_context_params; +} + +void SetupAtomURLRequestJobFactory( + content::ProtocolHandlerMap* protocol_handlers, + net::URLRequestContext* url_request_context, + AtomURLRequestJobFactory* job_factory) { + for (auto& protocol_handler : *protocol_handlers) { + job_factory->SetProtocolHandler( + protocol_handler.first, + base::WrapUnique(protocol_handler.second.release())); + } + protocol_handlers->clear(); + + job_factory->SetProtocolHandler(url::kAboutScheme, + std::make_unique()); + job_factory->SetProtocolHandler(url::kDataScheme, + std::make_unique()); + job_factory->SetProtocolHandler( + url::kFileScheme, + std::make_unique( + base::CreateTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_BLOCKING, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}))); + job_factory->SetProtocolHandler( + url::kHttpScheme, + std::make_unique(url::kHttpScheme)); + job_factory->SetProtocolHandler( + url::kHttpsScheme, + std::make_unique(url::kHttpsScheme)); + job_factory->SetProtocolHandler( + url::kWsScheme, std::make_unique(url::kWsScheme)); + job_factory->SetProtocolHandler( + url::kWssScheme, std::make_unique(url::kWssScheme)); + +#if !BUILDFLAG(DISABLE_FTP_SUPPORT) + auto* host_resolver = url_request_context->host_resolver(); + job_factory->SetProtocolHandler( + url::kFtpScheme, net::FtpProtocolHandler::Create(host_resolver)); +#endif +} + +void ApplyProxyModeFromCommandLine(ValueMapPrefStore* pref_store) { + if (!pref_store) + return; + + auto* command_line = base::CommandLine::ForCurrentProcess(); + + if (command_line->HasSwitch(::switches::kNoProxyServer)) { + pref_store->SetValue(proxy_config::prefs::kProxy, + ProxyConfigDictionary::CreateDirect(), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + } else if (command_line->HasSwitch(::switches::kProxyPacUrl)) { + std::string pac_script_url = + command_line->GetSwitchValueASCII(::switches::kProxyPacUrl); + pref_store->SetValue(proxy_config::prefs::kProxy, + ProxyConfigDictionary::CreatePacScript( + pac_script_url, false /* pac_mandatory */), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + } else if (command_line->HasSwitch(::switches::kProxyAutoDetect)) { + pref_store->SetValue(proxy_config::prefs::kProxy, + ProxyConfigDictionary::CreateAutoDetect(), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + } else if (command_line->HasSwitch(::switches::kProxyServer)) { + std::string proxy_server = + command_line->GetSwitchValueASCII(::switches::kProxyServer); + std::string bypass_list = + command_line->GetSwitchValueASCII(::switches::kProxyBypassList); + pref_store->SetValue( + proxy_config::prefs::kProxy, + ProxyConfigDictionary::CreateFixedServers(proxy_server, bypass_list), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + } +} + +} // namespace + +class ResourceContext : public content::ResourceContext { + public: + ResourceContext() = default; + ~ResourceContext() override = default; + + net::HostResolver* GetHostResolver() override { + if (request_context_) + return request_context_->host_resolver(); + return nullptr; + } + + net::URLRequestContext* GetRequestContext() override { + return request_context_; + } + + 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() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + LazyInitialize(); + return resource_context_.get(); +} + +scoped_refptr +URLRequestContextGetter::Handle::CreateMainRequestContextGetter( + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector protocol_interceptors) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!main_request_context_getter_.get()); + LazyInitialize(); + main_request_context_getter_ = new URLRequestContextGetter( + AtomBrowserClient::Get()->GetNetLog(), this, protocol_handlers, + std::move(protocol_interceptors)); + return main_request_context_getter_; +} + +scoped_refptr +URLRequestContextGetter::Handle::GetMainRequestContextGetter() { + return main_request_context_getter_; +} + +network::mojom::NetworkContextPtr +URLRequestContextGetter::Handle::GetNetworkContext() { + if (!main_network_context_) { + main_network_context_request_ = mojo::MakeRequest(&main_network_context_); + } + return std::move(main_network_context_); +} + +void URLRequestContextGetter::Handle::LazyInitialize() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (initialized_) + return; + + initialized_ = true; + main_network_context_params_ = CreateDefaultNetworkContextParams( + browser_context_->GetPath(), browser_context_->GetUserAgent(), + browser_context_->IsOffTheRecord(), browser_context_->CanUseHttpCache(), + browser_context_->GetMaxCacheSize()); + + browser_context_->proxy_config_monitor()->AddToNetworkContextParams( + main_network_context_params_.get()); + + ApplyProxyModeFromCommandLine(browser_context_->in_memory_pref_store()); + + if (!main_network_context_request_.is_pending()) { + main_network_context_request_ = mojo::MakeRequest(&main_network_context_); + } + content::BrowserContext::EnsureResourceContextInitialized( + browser_context_.get()); +} + +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( + net::NetLog* net_log, + URLRequestContextGetter::Handle* context_handle, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector protocol_interceptors) + : net_log_(net_log), + context_handle_(context_handle), + url_request_context_(nullptr), + protocol_interceptors_(std::move(protocol_interceptors)), + 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); +} + +URLRequestContextGetter::~URLRequestContextGetter() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // NotifyContextShuttingDown should have been called. + DCHECK(context_shutting_down_); +} + +void URLRequestContextGetter::NotifyContextShuttingDown( + std::unique_ptr resource_context) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + context_shutting_down_ = true; + resource_context.reset(); + net::URLRequestContextGetter::NotifyContextShuttingDown(); +} + +net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (context_shutting_down_) + return nullptr; + + if (!url_request_context_) { + auto& command_line = *base::CommandLine::ForCurrentProcess(); + std::unique_ptr builder = + std::make_unique(); + builder->set_network_delegate(std::make_unique()); + + ct_delegate_.reset(new brightray::RequireCTDelegate); + auto cert_verifier = std::make_unique(ct_delegate_.get()); + builder->SetCertVerifier(std::move(cert_verifier)); + + builder->SetCreateHttpTransactionFactoryCallback( + base::BindOnce(&content::CreateDevToolsNetworkTransactionFactory)); + + std::unique_ptr host_resolver = + net::HostResolver::CreateDefaultResolver(net_log_); + // --host-resolver-rules + if (command_line.HasSwitch(network::switches::kHostResolverRules)) { + auto remapped_resolver = + std::make_unique(std::move(host_resolver)); + remapped_resolver->SetRulesFromString(command_line.GetSwitchValueASCII( + network::switches::kHostResolverRules)); + host_resolver = std::move(remapped_resolver); + } + + net::HttpAuthPreferences auth_preferences; + // --auth-server-whitelist + if (command_line.HasSwitch(switches::kAuthServerWhitelist)) { + auth_preferences.SetServerWhitelist( + command_line.GetSwitchValueASCII(switches::kAuthServerWhitelist)); + } + + // --auth-negotiate-delegate-whitelist + if (command_line.HasSwitch(switches::kAuthNegotiateDelegateWhitelist)) { + auth_preferences.SetDelegateWhitelist(command_line.GetSwitchValueASCII( + switches::kAuthNegotiateDelegateWhitelist)); + } + auto http_auth_handler_factory = + net::HttpAuthHandlerRegistryFactory::CreateDefault(host_resolver.get()); + http_auth_handler_factory->SetHttpAuthPreferences(net::kNegotiateAuthScheme, + &auth_preferences); + builder->SetHttpAuthHandlerFactory(std::move(http_auth_handler_factory)); + builder->set_host_resolver(std::move(host_resolver)); + builder->set_ct_verifier(std::make_unique()); + + network_context_ = + content::GetNetworkServiceImpl()->CreateNetworkContextWithBuilder( + std::move(context_handle_->main_network_context_request_), + std::move(context_handle_->main_network_context_params_), + std::move(builder), &url_request_context_); + + net::TransportSecurityState* transport_security_state = + url_request_context_->transport_security_state(); + transport_security_state->SetRequireCTDelegate(ct_delegate_.get()); + + // Add custom standard schemes to cookie schemes. + auto* cookie_monster = + static_cast(url_request_context_->cookie_store()); + std::vector cookie_schemes( + {url::kHttpScheme, url::kHttpsScheme, url::kWsScheme, url::kWssScheme}); + const auto& custom_standard_schemes = atom::api::GetStandardSchemes(); + cookie_schemes.insert(cookie_schemes.end(), custom_standard_schemes.begin(), + custom_standard_schemes.end()); + cookie_monster->SetCookieableSchemes(cookie_schemes); + + // Setup handlers for custom job factory. + top_job_factory_.reset(new AtomURLRequestJobFactory); + SetupAtomURLRequestJobFactory(&protocol_handlers_, url_request_context_, + top_job_factory_.get()); + std::unique_ptr inner_job_factory( + new net::URLRequestJobFactoryImpl); + if (!protocol_interceptors_.empty()) { + // Set up interceptors in the reverse order. + for (auto it = protocol_interceptors_.rbegin(); + it != protocol_interceptors_.rend(); ++it) { + inner_job_factory.reset(new net::URLRequestInterceptingJobFactory( + std::move(inner_job_factory), std::move(*it))); + } + protocol_interceptors_.clear(); + } + top_job_factory_->Chain(std::move(inner_job_factory)); + url_request_context_->set_job_factory(top_job_factory_.get()); + + context_handle_->resource_context_->request_context_ = url_request_context_; + } + + return url_request_context_; +} + +scoped_refptr +URLRequestContextGetter::GetNetworkTaskRunner() const { + return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO); +} + +} // namespace atom diff --git a/atom/browser/net/url_request_context_getter.h b/atom/browser/net/url_request_context_getter.h new file mode 100644 index 0000000000000..dd8798eeebfa7 --- /dev/null +++ b/atom/browser/net/url_request_context_getter.h @@ -0,0 +1,117 @@ +// 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_NET_URL_REQUEST_CONTEXT_GETTER_H_ +#define ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_ + +#include +#include +#include + +#include "base/files/file_path.h" +#include "content/public/browser/browser_context.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_getter.h" +#include "services/network/public/mojom/network_service.mojom.h" + +#if DCHECK_IS_ON() +#include "base/debug/leak_tracker.h" +#endif + +namespace brightray { +class RequireCTDelegate; +} // namespace brightray + +namespace net { +class NetLog; +} + +namespace atom { + +class AtomBrowserContext; +class AtomURLRequestJobFactory; +class ResourceContext; + +class URLRequestContextGetter : public net::URLRequestContextGetter { + public: + // net::URLRequestContextGetter: + net::URLRequestContext* GetURLRequestContext() override; + scoped_refptr GetNetworkTaskRunner() + const override; + + // Discard reference to URLRequestContext and inform observers to + // shutdown. Must be called only on IO thread. + void NotifyContextShuttingDown(std::unique_ptr); + + AtomURLRequestJobFactory* job_factory() const { + return top_job_factory_.get(); + } + + private: + friend class AtomBrowserContext; + + // 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(); + scoped_refptr GetMainRequestContextGetter(); + network::mojom::NetworkContextPtr GetNetworkContext(); + + void ShutdownOnUIThread(); + + private: + friend class URLRequestContextGetter; + void LazyInitialize(); + + scoped_refptr main_request_context_getter_; + std::unique_ptr resource_context_; + base::WeakPtr browser_context_; + // This is a NetworkContext interface that uses URLRequestContextGetter + // NetworkContext, ownership is passed to StoragePartition when + // CreateMainNetworkContext is called. + network::mojom::NetworkContextPtr main_network_context_; + // Request corresponding to |main_network_context_|. Ownership + // is passed to network service. + network::mojom::NetworkContextRequest main_network_context_request_; + network::mojom::NetworkContextParamsPtr main_network_context_params_; + bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(Handle); + }; + + URLRequestContextGetter( + net::NetLog* net_log, + URLRequestContextGetter::Handle* context_handle, + content::ProtocolHandlerMap* protocol_handlers, + content::URLRequestInterceptorScopedVector protocol_interceptors); + ~URLRequestContextGetter() override; + +#if DCHECK_IS_ON() + base::debug::LeakTracker leak_tracker_; +#endif + + std::unique_ptr ct_delegate_; + std::unique_ptr top_job_factory_; + std::unique_ptr network_context_; + + net::NetLog* net_log_; + URLRequestContextGetter::Handle* context_handle_; + net::URLRequestContext* url_request_context_; + content::ProtocolHandlerMap protocol_handlers_; + content::URLRequestInterceptorScopedVector protocol_interceptors_; + bool context_shutting_down_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_URL_REQUEST_CONTEXT_GETTER_H_ diff --git a/atom/browser/net/url_request_fetch_job.cc b/atom/browser/net/url_request_fetch_job.cc index 68539433f4de8..5120baba73135 100644 --- a/atom/browser/net/url_request_fetch_job.cc +++ b/atom/browser/net/url_request_fetch_job.cc @@ -167,6 +167,9 @@ void URLRequestFetchJob::StartAsync(std::unique_ptr options) { request()->extra_request_headers().ToString()); fetcher_->Start(); + // URLFetcher has a refernce to the context, which + // will be cleared when the request is destroyed. + url_request_context_getter_ = nullptr; } void URLRequestFetchJob::HeadersCompleted() { @@ -199,6 +202,7 @@ int URLRequestFetchJob::DataAvailable(net::IOBuffer* buffer, void URLRequestFetchJob::Kill() { JsAsker::Kill(); fetcher_.reset(); + custom_browser_context_ = nullptr; } int URLRequestFetchJob::ReadRawData(net::IOBuffer* dest, int dest_size) { diff --git a/atom/browser/pref_store_delegate.cc b/atom/browser/pref_store_delegate.cc new file mode 100644 index 0000000000000..a577fde0d2963 --- /dev/null +++ b/atom/browser/pref_store_delegate.cc @@ -0,0 +1,30 @@ +// 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/pref_store_delegate.h" + +#include + +#include "atom/browser/atom_browser_context.h" +#include "components/prefs/value_map_pref_store.h" + +namespace atom { + +PrefStoreDelegate::PrefStoreDelegate( + base::WeakPtr browser_context) + : browser_context_(std::move(browser_context)) {} + +PrefStoreDelegate::~PrefStoreDelegate() { + if (browser_context_) + browser_context_->set_in_memory_pref_store(nullptr); +} + +void PrefStoreDelegate::UpdateCommandLinePrefStore( + PrefStore* command_line_prefs) { + if (browser_context_) + browser_context_->set_in_memory_pref_store( + static_cast(command_line_prefs)); +} + +} // namespace atom diff --git a/atom/browser/pref_store_delegate.h b/atom/browser/pref_store_delegate.h new file mode 100644 index 0000000000000..73696beb6fb07 --- /dev/null +++ b/atom/browser/pref_store_delegate.h @@ -0,0 +1,52 @@ +// 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_PREF_STORE_DELEGATE_H_ +#define ATOM_BROWSER_PREF_STORE_DELEGATE_H_ + +#include + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/prefs/persistent_pref_store.h" +#include "components/prefs/pref_value_store.h" + +namespace atom { + +class AtomBrowserContext; + +// Retrieves handle to the in memory pref store that gets +// initialized with the pref service. +class PrefStoreDelegate : public PrefValueStore::Delegate { + public: + explicit PrefStoreDelegate(base::WeakPtr browser_context); + ~PrefStoreDelegate() override; + + void Init(PrefStore* managed_prefs, + PrefStore* supervised_user_prefs, + PrefStore* extension_prefs, + PrefStore* command_line_prefs, + PrefStore* user_prefs, + PrefStore* recommended_prefs, + PrefStore* default_prefs, + PrefNotifier* pref_notifier) override {} + + void InitIncognitoUserPrefs( + scoped_refptr incognito_user_prefs_overlay, + scoped_refptr incognito_user_prefs_underlay, + const std::vector& overlay_pref_names) override {} + + void InitPrefRegistry(PrefRegistry* pref_registry) override {} + + void UpdateCommandLinePrefStore(PrefStore* command_line_prefs) override; + + private: + base::WeakPtr browser_context_; + + DISALLOW_COPY_AND_ASSIGN(PrefStoreDelegate); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_PREF_STORE_DELEGATE_H_ diff --git a/atom/browser/request_context_delegate.cc b/atom/browser/request_context_delegate.cc deleted file mode 100644 index 2bc44804878db..0000000000000 --- a/atom/browser/request_context_delegate.cc +++ /dev/null @@ -1,163 +0,0 @@ -// 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 deleted file mode 100644 index 7a6200a439f79..0000000000000 --- a/atom/browser/request_context_delegate.h +++ /dev/null @@ -1,58 +0,0 @@ -// 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/node_bindings.cc b/atom/common/node_bindings.cc index c9849a00183b5..64c11c9d15eb1 100644 --- a/atom/common/node_bindings.cc +++ b/atom/common/node_bindings.cc @@ -39,7 +39,6 @@ V(atom_browser_in_app_purchase) \ V(atom_browser_menu) \ V(atom_browser_net) \ - V(atom_browser_net_log) \ V(atom_browser_power_monitor) \ V(atom_browser_power_save_blocker) \ V(atom_browser_protocol) \ diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 69217ec1a1154..7de8d1747babd 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -218,6 +218,13 @@ const char kDiskCacheSize[] = "disk-cache-size"; // Ignore the limit of 6 connections per host. const char kIgnoreConnectionsLimit[] = "ignore-connections-limit"; +// Whitelist containing servers for which Integrated Authentication is enabled. +const char kAuthServerWhitelist[] = "auth-server-whitelist"; + +// Whitelist containing servers for which Kerberos delegation is allowed. +const char kAuthNegotiateDelegateWhitelist[] = + "auth-negotiate-delegate-whitelist"; + } // namespace switches } // namespace atom diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index cadadc16939cd..a6b1e404fa032 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -113,6 +113,8 @@ extern const char kWidevineCdmVersion[]; extern const char kDiskCacheSize[]; extern const char kIgnoreConnectionsLimit[]; +extern const char kAuthServerWhitelist[]; +extern const char kAuthNegotiateDelegateWhitelist[]; } // namespace switches diff --git a/atom/utility/atom_content_utility_client.cc b/atom/utility/atom_content_utility_client.cc index e2a856d53ae24..3a9cfff38d67e 100644 --- a/atom/utility/atom_content_utility_client.cc +++ b/atom/utility/atom_content_utility_client.cc @@ -4,6 +4,10 @@ #include "atom/utility/atom_content_utility_client.h" +#include "content/public/child/child_thread.h" +#include "services/proxy_resolver/proxy_resolver_service.h" +#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h" + #if defined(OS_WIN) #include "chrome/utility/printing_handler_win.h" #endif @@ -29,4 +33,14 @@ bool AtomContentUtilityClient::OnMessageReceived(const IPC::Message& message) { return false; } +void AtomContentUtilityClient::RegisterServices(StaticServiceMap* services) { + service_manager::EmbeddedServiceInfo proxy_resolver_info; + proxy_resolver_info.task_runner = + content::ChildThread::Get()->GetIOTaskRunner(); + proxy_resolver_info.factory = + base::BindRepeating(&proxy_resolver::ProxyResolverService::CreateService); + services->emplace(proxy_resolver::mojom::kProxyResolverServiceName, + proxy_resolver_info); +} + } // namespace atom diff --git a/atom/utility/atom_content_utility_client.h b/atom/utility/atom_content_utility_client.h index 7694970457b74..cf990a40ddcb6 100644 --- a/atom/utility/atom_content_utility_client.h +++ b/atom/utility/atom_content_utility_client.h @@ -21,6 +21,7 @@ class AtomContentUtilityClient : public content::ContentUtilityClient { ~AtomContentUtilityClient() override; bool OnMessageReceived(const IPC::Message& message) override; + void RegisterServices(StaticServiceMap* services) override; private: #if defined(OS_WIN) diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp index 5b353f0a7a9b5..3dbc3c90655b6 100644 --- a/brightray/brightray.gyp +++ b/brightray/brightray.gyp @@ -150,8 +150,8 @@ '<(libchromiumcontent_dir)/libfx_agg.a', '<(libchromiumcontent_dir)/libfx_lcms2.a', '<(libchromiumcontent_dir)/libfx_libopenjpeg.a', - '<(libchromiumcontent_dir)/libfx_zlib.a', '-Wl,--no-whole-archive', + '<(libchromiumcontent_dir)/libchrome.a', ], }, }, { @@ -221,6 +221,7 @@ '<(libchromiumcontent_dir)/librenderer.a', '<(libchromiumcontent_dir)/libsecurity_state.a', '<(libchromiumcontent_dir)/libviz_service.a', + '<(libchromiumcontent_dir)/libchrome.a', # services/device/wake_lock/power_save_blocker/ '<(libchromiumcontent_dir)/libpower_save_blocker.a', # Friends of libpdf.a: @@ -360,6 +361,7 @@ '<(libchromiumcontent_dir)/renderer.lib', '<(libchromiumcontent_dir)/security_state.lib', '<(libchromiumcontent_dir)/viz_service.lib', + '<(libchromiumcontent_dir)/chrome.lib', # services/device/wake_lock/power_save_blocker/ '<(libchromiumcontent_dir)/power_save_blocker.lib', # Friends of pdf.lib: diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc index b2b7d36301f40..4f8d75f44076e 100644 --- a/brightray/browser/browser_client.cc +++ b/brightray/browser/browser_client.cc @@ -6,7 +6,6 @@ #include "base/lazy_instance.h" #include "base/path_service.h" -#include "brightray/browser/browser_context.h" #include "brightray/browser/browser_main_parts.h" #include "brightray/browser/devtools_manager_delegate.h" #include "brightray/browser/media/media_capture_devices_dispatcher.h" @@ -106,10 +105,6 @@ void BrowserClient::GetAdditionalWebUISchemes( additional_schemes->push_back(content::kChromeDevToolsScheme); } -NetLog* BrowserClient::GetNetLog() { - return &net_log_; -} - base::FilePath BrowserClient::GetDefaultDownloadDirectory() { // ~/Downloads base::FilePath path; diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h index 643e493f43fe8..ab640f332999e 100644 --- a/brightray/browser/browser_client.h +++ b/brightray/browser/browser_client.h @@ -8,7 +8,6 @@ #include #include -#include "brightray/browser/net_log.h" #include "content/public/browser/content_browser_client.h" namespace brightray { @@ -45,7 +44,6 @@ class BrowserClient : public content::ContentBrowserClient { std::vector* additional_schemes) override; void GetAdditionalWebUISchemes( std::vector* additional_schemes) override; - NetLog* GetNetLog() override; base::FilePath GetDefaultDownloadDirectory() override; content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; std::string GetApplicationLocale() override; @@ -59,7 +57,6 @@ class BrowserClient : public content::ContentBrowserClient { private: BrowserMainParts* browser_main_parts_; - NetLog net_log_; std::unique_ptr notification_service_; std::unique_ptr notification_presenter_; diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc deleted file mode 100644 index 708a97bddd1e8..0000000000000 --- a/brightray/browser/browser_context.cc +++ /dev/null @@ -1,211 +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/browser_context.h" - -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "base/threading/thread_restrictions.h" -#include "brightray/browser/brightray_paths.h" -#include "brightray/browser/browser_client.h" -#include "brightray/browser/inspectable_web_contents_impl.h" -#include "brightray/browser/special_storage_policy.h" -#include "brightray/browser/zoom_level_delegate.h" -#include "brightray/common/application_info.h" -#include "components/prefs/json_pref_store.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service.h" -#include "components/prefs/pref_service_factory.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/storage_partition.h" -#include "net/base/escape.h" - -using content::BrowserThread; - -namespace brightray { - -namespace { - -// Convert string to lower case and escape it. -std::string MakePartitionName(const std::string& input) { - return net::EscapePath(base::ToLowerASCII(input)); -} - -} // namespace - -// static -void BrowserContextDeleter::Destruct(const BrowserContext* browser_context) { - browser_context->OnDestruct(); -} - -// static -BrowserContext::BrowserContextMap BrowserContext::browser_context_map_; - -// static -scoped_refptr BrowserContext::Get(const std::string& partition, - bool in_memory) { - PartitionKey key(partition, in_memory); - if (browser_context_map_[key].get()) - return WrapRefCounted(browser_context_map_[key].get()); - - return nullptr; -} - -BrowserContext::BrowserContext(const std::string& partition, bool in_memory) - : in_memory_(in_memory), - storage_policy_(new SpecialStoragePolicy), - weak_factory_(this) { - if (!PathService::Get(DIR_USER_DATA, &path_)) { - PathService::Get(DIR_APP_DATA, &path_); - path_ = path_.Append(base::FilePath::FromUTF8Unsafe(GetApplicationName())); - PathService::Override(DIR_USER_DATA, path_); - } - - if (!in_memory_ && !partition.empty()) - path_ = path_.Append(FILE_PATH_LITERAL("Partitions")) - .Append(base::FilePath::FromUTF8Unsafe( - MakePartitionName(partition))); - - content::BrowserContext::Initialize(this, path_); - - io_handle_ = new URLRequestContextGetter::Handle(GetWeakPtr()); - - browser_context_map_[PartitionKey(partition, in_memory)] = GetWeakPtr(); -} - -BrowserContext::~BrowserContext() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - NotifyWillBeDestroyed(this); - ShutdownStoragePartitions(); - io_handle_->ShutdownOnUIThread(); -} - -void BrowserContext::OnDestruct() const { - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - delete this; - } else { - BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); - } -} - -void BrowserContext::InitPrefs() { - auto prefs_path = GetPath().Append(FILE_PATH_LITERAL("Preferences")); - base::ThreadRestrictions::ScopedAllowIO allow_io; - PrefServiceFactory prefs_factory; - scoped_refptr pref_store = - base::MakeRefCounted(prefs_path); - pref_store->ReadPrefs(); // Synchronous. - prefs_factory.set_user_prefs(pref_store); - - auto registry = WrapRefCounted(new PrefRegistrySimple); - RegisterInternalPrefs(registry.get()); - RegisterPrefs(registry.get()); - - prefs_ = prefs_factory.Create(registry.get()); -} - -void BrowserContext::RegisterInternalPrefs(PrefRegistrySimple* registry) { - InspectableWebContentsImpl::RegisterPrefs(registry); - MediaDeviceIDSalt::RegisterPrefs(registry); - ZoomLevelDelegate::RegisterPrefs(registry); -} - -URLRequestContextGetter* BrowserContext::GetRequestContext() { - return static_cast( - GetDefaultStoragePartition(this)->GetURLRequestContext()); -} - -net::URLRequestContextGetter* BrowserContext::CreateRequestContext( - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector protocol_interceptors) { - return io_handle_ - ->CreateMainRequestContextGetter(protocol_handlers, - std::move(protocol_interceptors)) - .get(); -} - -std::string BrowserContext::GetMediaDeviceIDSalt() { - if (!media_device_id_salt_.get()) - media_device_id_salt_.reset(new MediaDeviceIDSalt(prefs_.get())); - return media_device_id_salt_->GetSalt(); -} - -base::FilePath BrowserContext::GetPath() const { - return path_; -} - -std::unique_ptr -BrowserContext::CreateZoomLevelDelegate(const base::FilePath& partition_path) { - if (!IsOffTheRecord()) { - return std::make_unique(prefs(), partition_path); - } - return std::unique_ptr(); -} - -bool BrowserContext::IsOffTheRecord() const { - return in_memory_; -} - -content::ResourceContext* BrowserContext::GetResourceContext() { - return io_handle_->GetResourceContext(); -} - -content::DownloadManagerDelegate* BrowserContext::GetDownloadManagerDelegate() { - return nullptr; -} - -content::BrowserPluginGuestManager* BrowserContext::GetGuestManager() { - return nullptr; -} - -storage::SpecialStoragePolicy* BrowserContext::GetSpecialStoragePolicy() { - return storage_policy_.get(); -} - -content::PushMessagingService* BrowserContext::GetPushMessagingService() { - return nullptr; -} - -content::SSLHostStateDelegate* BrowserContext::GetSSLHostStateDelegate() { - return nullptr; -} - -content::BackgroundFetchDelegate* BrowserContext::GetBackgroundFetchDelegate() { - return nullptr; -} - -content::BackgroundSyncController* -BrowserContext::GetBackgroundSyncController() { - return nullptr; -} - -content::BrowsingDataRemoverDelegate* -BrowserContext::GetBrowsingDataRemoverDelegate() { - return nullptr; -} - -net::URLRequestContextGetter* -BrowserContext::CreateRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory, - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector request_interceptors) { - NOTREACHED(); - return nullptr; -} - -net::URLRequestContextGetter* BrowserContext::CreateMediaRequestContext() { - return io_handle_->GetMainRequestContextGetter().get(); -} - -net::URLRequestContextGetter* -BrowserContext::CreateMediaRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory) { - NOTREACHED(); - return nullptr; -} - -} // namespace brightray diff --git a/brightray/browser/browser_context.h b/brightray/browser/browser_context.h deleted file mode 100644 index d36ec3bbdff9a..0000000000000 --- a/brightray/browser/browser_context.h +++ /dev/null @@ -1,138 +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_BROWSER_CONTEXT_H_ -#define BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_ - -#include -#include - -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "brightray/browser/media/media_device_id_salt.h" -#include "brightray/browser/url_request_context_getter.h" -#include "content/public/browser/browser_context.h" - -class PrefRegistrySimple; -class PrefService; - -namespace storage { -class SpecialStoragePolicy; -} - -namespace brightray { - -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. - static scoped_refptr Get(const std::string& partition, - bool in_memory); - - base::WeakPtr GetWeakPtr() { - return weak_factory_.GetWeakPtr(); - } - - // Get the request context, if there is no one, create it. - URLRequestContextGetter* GetRequestContext(); - - // content::BrowserContext: - std::unique_ptr CreateZoomLevelDelegate( - const base::FilePath& partition_path) override; - bool IsOffTheRecord() const override; - content::ResourceContext* GetResourceContext() override; - content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; - content::BrowserPluginGuestManager* GetGuestManager() override; - storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override; - content::PushMessagingService* GetPushMessagingService() override; - content::SSLHostStateDelegate* GetSSLHostStateDelegate() override; - content::BackgroundFetchDelegate* GetBackgroundFetchDelegate() override; - content::BackgroundSyncController* GetBackgroundSyncController() override; - content::BrowsingDataRemoverDelegate* GetBrowsingDataRemoverDelegate() - override; - net::URLRequestContextGetter* CreateRequestContext( - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector request_interceptors) override; - net::URLRequestContextGetter* CreateRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory, - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector request_interceptors) override; - net::URLRequestContextGetter* CreateMediaRequestContext() override; - net::URLRequestContextGetter* CreateMediaRequestContextForStoragePartition( - const base::FilePath& partition_path, - bool in_memory) override; - std::string GetMediaDeviceIDSalt() override; - 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; - - // Subclasses should override this to register custom preferences. - virtual void RegisterPrefs(PrefRegistrySimple* pref_registry) {} - - private: - 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 { - std::string partition; - bool in_memory; - - PartitionKey(const std::string& partition, bool in_memory) - : partition(partition), in_memory(in_memory) {} - - bool operator<(const PartitionKey& other) const { - if (partition == other.partition) - return in_memory < other.in_memory; - return partition < other.partition; - } - - bool operator==(const PartitionKey& other) const { - return (partition == other.partition) && (in_memory == other.in_memory); - } - }; - using BrowserContextMap = - std::map>; - static BrowserContextMap browser_context_map_; - - base::FilePath path_; - bool in_memory_; - - 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_; - - DISALLOW_COPY_AND_ASSIGN(BrowserContext); -}; - -} // namespace brightray - -#endif // BRIGHTRAY_BROWSER_BROWSER_CONTEXT_H_ diff --git a/brightray/browser/browser_main_parts.cc b/brightray/browser/browser_main_parts.cc index ec586b9e8a6c2..92808bdcbd81f 100644 --- a/brightray/browser/browser_main_parts.cc +++ b/brightray/browser/browser_main_parts.cc @@ -22,7 +22,6 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "brightray/browser/browser_client.h" -#include "brightray/browser/browser_context.h" #include "brightray/browser/devtools_manager_delegate.h" #include "brightray/browser/media/media_capture_devices_dispatcher.h" #include "brightray/browser/web_ui_controller_factory.h" @@ -318,9 +317,6 @@ int BrowserMainParts::PreCreateThreads() { BrowserClient::SetApplicationLocale( l10n_util::GetApplicationLocale(custom_locale_)); - // Manage global state of net and other IO thread related. - io_thread_ = std::make_unique(); - return 0; } @@ -329,8 +325,6 @@ void BrowserMainParts::PostDestroyThreads() { device::BluetoothAdapterFactory::Shutdown(); bluez::DBusBluezManagerWrapperLinux::Shutdown(); #endif - - io_thread_.reset(); } } // namespace brightray diff --git a/brightray/browser/browser_main_parts.h b/brightray/browser/browser_main_parts.h index cf8e0296585b1..f4e345540b673 100644 --- a/brightray/browser/browser_main_parts.h +++ b/brightray/browser/browser_main_parts.h @@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/path_service.h" #include "brightray/browser/brightray_paths.h" -#include "brightray/browser/io_thread.h" #include "content/public/browser/browser_main_parts.h" #include "ui/views/layout/layout_provider.h" @@ -29,8 +28,6 @@ class BrowserMainParts : public content::BrowserMainParts { BrowserMainParts(); ~BrowserMainParts() override; - IOThread* io_thread() const { return io_thread_.get(); } - protected: // content::BrowserMainParts: bool ShouldContentCreateFeatureList() override; @@ -51,8 +48,6 @@ class BrowserMainParts : public content::BrowserMainParts { void OverrideAppLogsPath(); #endif - std::unique_ptr io_thread_; - #if defined(USE_AURA) std::unique_ptr wm_state_; #endif diff --git a/brightray/browser/inspectable_web_contents.cc b/brightray/browser/inspectable_web_contents.cc index ab6d87d6c6922..e7c350a3e5c32 100644 --- a/brightray/browser/inspectable_web_contents.cc +++ b/brightray/browser/inspectable_web_contents.cc @@ -6,8 +6,9 @@ namespace brightray { InspectableWebContents* InspectableWebContents::Create( content::WebContents* web_contents, + PrefService* pref_service, bool is_guest) { - return new InspectableWebContentsImpl(web_contents, is_guest); + return new InspectableWebContentsImpl(web_contents, pref_service, is_guest); } } // namespace brightray diff --git a/brightray/browser/inspectable_web_contents.h b/brightray/browser/inspectable_web_contents.h index 4abaa03c5f9c9..f659de1b2fa74 100644 --- a/brightray/browser/inspectable_web_contents.h +++ b/brightray/browser/inspectable_web_contents.h @@ -13,6 +13,8 @@ namespace content { class DevToolsAgentHost; } +class PrefService; + namespace brightray { class InspectableWebContentsDelegate; @@ -23,6 +25,7 @@ class InspectableWebContents { // The returned InspectableWebContents takes ownership of the passed-in // WebContents. static InspectableWebContents* Create(content::WebContents* web_contents, + PrefService* pref_service, bool is_guest); virtual ~InspectableWebContents() {} diff --git a/brightray/browser/inspectable_web_contents_impl.cc b/brightray/browser/inspectable_web_contents_impl.cc index 2954e428d66e4..2f6b818c7646b 100644 --- a/brightray/browser/inspectable_web_contents_impl.cc +++ b/brightray/browser/inspectable_web_contents_impl.cc @@ -18,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "brightray/browser/browser_client.h" -#include "brightray/browser/browser_context.h" #include "brightray/browser/browser_main_parts.h" #include "brightray/browser/inspectable_web_contents_delegate.h" #include "brightray/browser/inspectable_web_contents_view.h" @@ -26,13 +25,16 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/storage_partition.h" #include "content/public/common/user_agent.h" #include "ipc/ipc_channel.h" +#include "net/base/io_buffer.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher_response_writer.h" @@ -203,13 +205,12 @@ void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) { InspectableWebContentsImpl::InspectableWebContentsImpl( content::WebContents* web_contents, + PrefService* pref_service, bool is_guest) : frontend_loaded_(false), can_dock_(true), delegate_(nullptr), - pref_service_( - static_cast(web_contents->GetBrowserContext()) - ->prefs()), + pref_service_(pref_service), web_contents_(web_contents), is_guest_(is_guest), view_(CreateInspectableContentsView(this)), @@ -485,13 +486,14 @@ void InspectableWebContentsImpl::LoadNetworkResource( return; } - auto* browser_context = static_cast( - GetDevToolsWebContents()->GetBrowserContext()); + auto* browser_context = GetDevToolsWebContents()->GetBrowserContext(); net::URLFetcher* fetcher = (net::URLFetcher::Create(gurl, net::URLFetcher::GET, this)).release(); pending_requests_[fetcher] = callback; - fetcher->SetRequestContext(browser_context->GetRequestContext()); + fetcher->SetRequestContext( + content::BrowserContext::GetDefaultStoragePartition(browser_context) + ->GetURLRequestContext()); fetcher->SetExtraRequestHeaders(headers); fetcher->SaveResponseWithWriter( std::unique_ptr( diff --git a/brightray/browser/inspectable_web_contents_impl.h b/brightray/browser/inspectable_web_contents_impl.h index 03ff1e8482cfe..d42f8a4ad78fe 100644 --- a/brightray/browser/inspectable_web_contents_impl.h +++ b/brightray/browser/inspectable_web_contents_impl.h @@ -39,7 +39,9 @@ class InspectableWebContentsImpl public: static void RegisterPrefs(PrefRegistrySimple* pref_registry); - InspectableWebContentsImpl(content::WebContents* web_contents, bool is_guest); + InspectableWebContentsImpl(content::WebContents* web_contents, + PrefService* pref_service, + bool is_guest); ~InspectableWebContentsImpl() override; InspectableWebContentsView* GetView() const override; diff --git a/brightray/browser/io_thread.cc b/brightray/browser/io_thread.cc deleted file mode 100644 index 4528cf7bfa576..0000000000000 --- a/brightray/browser/io_thread.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2017 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "brightray/browser/io_thread.h" - -#include "content/public/browser/browser_thread.h" -#include "net/proxy_resolution/proxy_service.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" - -#if defined(USE_NSS_CERTS) -#include "net/cert_net/nss_ocsp.h" -#endif - -using content::BrowserThread; - -namespace brightray { - -IOThread::IOThread() { - BrowserThread::SetIOThreadDelegate(this); -} - -IOThread::~IOThread() { - BrowserThread::SetIOThreadDelegate(nullptr); -} - -void IOThread::Init() { - net::URLRequestContextBuilder builder; - 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()); - url_request_context_getter_->AddRef(); - -#if defined(USE_NSS_CERTS) - net::SetMessageLoopForNSSHttpIO(); - net::SetURLRequestContextForNSSHttpIO(url_request_context_.get()); -#endif -} - -void IOThread::CleanUp() { -#if defined(USE_NSS_CERTS) - net::ShutdownNSSHttpIO(); - net::SetURLRequestContextForNSSHttpIO(nullptr); -#endif - // Explicitly release before the IO thread gets destroyed. - url_request_context_getter_->Release(); - url_request_context_.reset(); -} - -} // namespace brightray diff --git a/brightray/browser/net_log.cc b/brightray/browser/net_log.cc deleted file mode 100644 index fb443ea0b72b9..0000000000000 --- a/brightray/browser/net_log.cc +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2015 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "brightray/browser/net_log.h" - -#include - -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/values.h" -#include "net/log/file_net_log_observer.h" -#include "net/log/net_log_util.h" -#include "services/network/public/cpp/network_switches.h" - -namespace brightray { - -namespace { - -std::unique_ptr GetConstants() { - std::unique_ptr constants = net::GetNetConstants(); - - // Adding client information to constants dictionary. - auto client_info = std::make_unique(); - client_info->SetString( - "command_line", - base::CommandLine::ForCurrentProcess()->GetCommandLineString()); - - constants->Set("clientInfo", std::move(client_info)); - return constants; -} - -} // namespace - -NetLog::NetLog() {} - -NetLog::~NetLog() { - StopDynamicLogging(); - StopLogging(); -} - -void NetLog::StartLogging() { - auto* command_line = base::CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(network::switches::kLogNetLog)) - return; - - base::FilePath log_path = - command_line->GetSwitchValuePath(network::switches::kLogNetLog); - if (log_path.empty()) - return; - - std::unique_ptr constants(GetConstants()); // Net constants - net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default(); - - file_net_log_observer_ = - net::FileNetLogObserver::CreateUnbounded(log_path, std::move(constants)); - file_net_log_observer_->StartObserving(this, capture_mode); -} - -void NetLog::StopLogging() { - if (!file_net_log_observer_) - return; - - file_net_log_observer_->StopObserving(nullptr, base::OnceClosure()); - file_net_log_observer_.reset(); -} - -void NetLog::StartDynamicLogging(const base::FilePath& log_path) { - if (dynamic_file_net_log_observer_ || log_path.empty()) - return; - - dynamic_file_net_log_path_ = log_path; - - std::unique_ptr constants(GetConstants()); // Net constants - net::NetLogCaptureMode capture_mode = net::NetLogCaptureMode::Default(); - - dynamic_file_net_log_observer_ = net::FileNetLogObserver::CreateUnbounded( - dynamic_file_net_log_path_, std::move(constants)); - dynamic_file_net_log_observer_->StartObserving(this, capture_mode); -} - -bool NetLog::IsDynamicLogging() { - return !!dynamic_file_net_log_observer_; -} - -base::FilePath NetLog::GetDynamicLoggingPath() { - return dynamic_file_net_log_path_; -} - -void NetLog::StopDynamicLogging(base::OnceClosure callback) { - if (!dynamic_file_net_log_observer_) { - if (callback) - std::move(callback).Run(); - return; - } - - dynamic_file_net_log_observer_->StopObserving(nullptr, std::move(callback)); - dynamic_file_net_log_observer_.reset(); - - dynamic_file_net_log_path_ = base::FilePath(); -} - -} // namespace brightray diff --git a/brightray/browser/net_log.h b/brightray/browser/net_log.h deleted file mode 100644 index ffeb85f78a969..0000000000000 --- a/brightray/browser/net_log.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2015 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_LOG_H_ -#define BRIGHTRAY_BROWSER_NET_LOG_H_ - -#include "base/callback.h" -#include "base/files/file_path.h" -#include "net/log/net_log.h" - -namespace net { -class FileNetLogObserver; -} - -namespace brightray { - -class NetLog : public net::NetLog { - public: - NetLog(); - ~NetLog() override; - - void StartLogging(); - void StopLogging(); - - void StartDynamicLogging(const base::FilePath& path); - bool IsDynamicLogging(); - base::FilePath GetDynamicLoggingPath(); - void StopDynamicLogging(base::OnceClosure callback = base::OnceClosure()); - - private: - // This observer handles writing NetLogs. - std::unique_ptr file_net_log_observer_; - std::unique_ptr dynamic_file_net_log_observer_; - base::FilePath dynamic_file_net_log_path_; - - DISALLOW_COPY_AND_ASSIGN(NetLog); -}; - -} // namespace brightray - -#endif // BRIGHTRAY_BROWSER_NET_LOG_H_ diff --git a/brightray/browser/url_request_context_getter.cc b/brightray/browser/url_request_context_getter.cc deleted file mode 100644 index 7a02e9b1aaa14..0000000000000 --- a/brightray/browser/url_request_context_getter.cc +++ /dev/null @@ -1,426 +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/url_request_context_getter.h" - -#include - -#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/browser_context.h" -#include "brightray/browser/net/require_ct_delegate.h" -#include "brightray/browser/net_log.h" -#include "brightray/common/switches.h" -#include "components/network_session_configurator/common/network_switches.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 "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" -#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/extras/sqlite/sqlite_channel_id_store.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 { - -class ResourceContext : public content::ResourceContext { - public: - ResourceContext() = default; - ~ResourceContext() override = default; - - net::HostResolver* GetHostResolver() override { - if (request_context_) - return request_context_->host_resolver(); - return nullptr; - } - - net::URLRequestContext* GetRequestContext() override { - return request_context_; - } - - 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(); -} - -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_; -} - -scoped_refptr -URLRequestContextGetter::Handle::GetMainRequestContextGetter() const { - return main_request_context_getter_; -} - -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); - 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( - NetLog* net_log, - ResourceContext* resource_context, - bool in_memory, - const std::string& user_agent, - const base::FilePath& base_path, - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector protocol_interceptors) - : 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), - user_agent_(user_agent), - 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); - - // 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( - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); -} - -URLRequestContextGetter::~URLRequestContextGetter() {} - -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(); - ct_delegate_.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_); - } - - storage_.reset( - new net::URLRequestContextStorage(url_request_context_.get())); - - storage_->set_network_delegate(delegate_->CreateNetworkDelegate()); - - std::unique_ptr cookie_store; - scoped_refptr channel_id_db; - // Create a single task runner to use with the CookieStore and - // ChannelIDStore. - scoped_refptr cookie_background_task_runner = - base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BACKGROUND, - base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); - auto cookie_path = in_memory_ - ? base::FilePath() - : base_path_.Append(FILE_PATH_LITERAL("Cookies")); - if (!in_memory_) { - channel_id_db = new net::SQLiteChannelIDStore( - base_path_.Append(FILE_PATH_LITERAL("Origin Bound Certs")), - cookie_background_task_runner); - } - std::unique_ptr channel_id_service( - new net::ChannelIDService( - new net::DefaultChannelIDStore(channel_id_db.get()))); - content::CookieStoreConfig cookie_config(cookie_path, false, false, - nullptr); - cookie_config.channel_id_service = channel_id_service.get(); - cookie_config.background_task_runner = cookie_background_task_runner; - cookie_store = content::CreateCookieStore(cookie_config); - cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID()); - - // Set custom schemes that can accept cookies. - net::CookieMonster* cookie_monster = - static_cast(cookie_store.get()); - 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_ = - cookie_store->GetChangeDispatcher().AddCallbackForAllChanges( - base::Bind(&URLRequestContextGetter::OnCookieChanged, - base::RetainedRef(this))); - storage_->set_cookie_store(std::move(cookie_store)); - storage_->set_channel_id_service(std::move(channel_id_service)); - - storage_->set_http_user_agent_settings( - base::WrapUnique(new net::StaticHttpUserAgentSettings( - net::HttpUtil::GenerateAcceptLanguageHeader( - BrowserClient::Get()->GetApplicationLocale()), - user_agent_))); - - std::unique_ptr host_resolver( - net::HostResolver::CreateDefaultResolver(nullptr)); - - // --host-resolver-rules - if (command_line.HasSwitch(network::switches::kHostResolverRules)) { - std::unique_ptr 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 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 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(new net::SSLConfigServiceDefaults()); - storage_->set_http_auth_handler_factory(std::move(auth_handler_factory)); - std::unique_ptr server_properties( - new net::HttpServerPropertiesImpl); - storage_->set_http_server_properties(std::move(server_properties)); - - std::unique_ptr ct_verifier = - std::make_unique(); - ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs()); - storage_->set_cert_transparency_verifier(std::move(ct_verifier)); - storage_->set_ct_policy_enforcer(std::make_unique()); - - 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 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( - content::CreateDevToolsNetworkTransactionFactory( - http_network_session_.get()), - std::move(backend), false)); - - std::unique_ptr job_factory = - delegate_->CreateURLRequestJobFactory(url_request_context_.get(), - &protocol_handlers_); - job_factory_ = job_factory.get(); - - // Set up interceptors in the reverse order. - std::unique_ptr 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)); - } - - if (resource_context_) - resource_context_->request_context_ = url_request_context_.get(); - - return url_request_context_.get(); -} - -scoped_refptr -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 deleted file mode 100644 index 941a5782b14a9..0000000000000 --- a/brightray/browser/url_request_context_getter.h +++ /dev/null @@ -1,149 +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_URL_REQUEST_CONTEXT_GETTER_H_ -#define BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_ - -#include -#include - -#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 "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" - -#if DCHECK_IS_ON() -#include "base/debug/leak_tracker.h" -#endif - -namespace net { -class HostMappingRules; -class HostResolver; -class HttpAuthPreferences; -class NetworkDelegate; -class ProxyConfigService; -class URLRequestContextStorage; -class URLRequestJobFactory; -} // namespace net - -namespace brightray { - -class BrowserContext; -class ResourceContext; -class RequireCTDelegate; -class NetLog; - -class URLRequestContextGetter : public net::URLRequestContextGetter { - public: - class Delegate { - public: - Delegate() {} - virtual ~Delegate() {} - - virtual std::unique_ptr CreateNetworkDelegate() = 0; - virtual std::unique_ptr - CreateURLRequestJobFactory( - net::URLRequestContext* url_request_context, - content::ProtocolHandlerMap* protocol_handlers) = 0; - virtual net::HttpCache::BackendFactory* CreateHttpCacheBackendFactory( - const base::FilePath& base_path) = 0; - virtual std::unique_ptr CreateCertVerifier( - RequireCTDelegate* ct_delegate) = 0; - virtual void GetCookieableSchemes( - std::vector* cookie_schemes) {} - virtual void OnCookieChanged(const net::CanonicalCookie& cookie, - net::CookieChangeCause cause) {} - }; - - URLRequestContextGetter( - NetLog* net_log, - ResourceContext* resource_context, - bool in_memory, - const std::string& user_agent, - const base::FilePath& base_path, - content::ProtocolHandlerMap* protocol_handlers, - content::URLRequestInterceptorScopedVector protocol_interceptors); - - // net::URLRequestContextGetter: - net::URLRequestContext* GetURLRequestContext() override; - scoped_refptr GetNetworkTaskRunner() - const override; - - net::URLRequestJobFactory* job_factory() const { return job_factory_; } - void set_delegate(Delegate* delegate) { delegate_ = delegate; } - - // 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; - - // net::CookieChangeDispatcher::CookieChangedCallback implementation. - void OnCookieChanged(const net::CanonicalCookie& cookie, - net::CookieChangeCause cause) const; - -#if DCHECK_IS_ON() - base::debug::LeakTracker leak_tracker_; -#endif - - std::unique_ptr ct_delegate_; - std::unique_ptr proxy_config_service_; - std::unique_ptr storage_; - std::unique_ptr url_request_context_; - std::unique_ptr host_mapping_rules_; - 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_; - base::FilePath base_path_; - bool in_memory_; - std::string user_agent_; - bool context_shutting_down_; - - DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter); -}; - -} // namespace brightray - -#endif // BRIGHTRAY_BROWSER_URL_REQUEST_CONTEXT_GETTER_H_ diff --git a/brightray/common/switches.cc b/brightray/common/switches.cc deleted file mode 100644 index ef7a138375bd7..0000000000000 --- a/brightray/common/switches.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2016 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "brightray/common/switches.h" - -namespace brightray { - -namespace switches { - -// Comma-separated list of rules that control how hostnames are mapped. -// -// For example: -// "MAP * 127.0.0.1" --> Forces all hostnames to be mapped to 127.0.0.1 -// "MAP *.google.com proxy" --> Forces all google.com subdomains to be -// resolved to "proxy". -// "MAP test.com [::1]:77 --> Forces "test.com" to resolve to IPv6 loopback. -// Will also force the port of the resulting -// socket address to be 77. -// "MAP * baz, EXCLUDE www.google.com" --> Remaps everything to "baz", -// except for "www.google.com". -// -// These mappings apply to the endpoint host in a net::URLRequest (the TCP -// connect and host resolver in a direct connection, and the CONNECT in an http -// proxy connection, and the endpoint host in a SOCKS proxy connection). -const char kHostRules[] = "host-rules"; - -// Don't use a proxy server, always make direct connections. Overrides any -// other proxy server flags that are passed. -const char kNoProxyServer[] = "no-proxy-server"; - -// Uses a specified proxy server, overrides system settings. This switch only -// affects HTTP and HTTPS requests. -const char kProxyServer[] = "proxy-server"; - -// Bypass specified proxy for the given semi-colon-separated list of hosts. This -// flag has an effect only when --proxy-server is set. -const char kProxyBypassList[] = "proxy-bypass-list"; - -// Uses the pac script at the given URL. -const char kProxyPacUrl[] = "proxy-pac-url"; - -// Disable HTTP/2 and SPDY/3.1 protocols. -const char kDisableHttp2[] = "disable-http2"; - -// Whitelist containing servers for which Integrated Authentication is enabled. -const char kAuthServerWhitelist[] = "auth-server-whitelist"; - -// Whitelist containing servers for which Kerberos delegation is allowed. -const char kAuthNegotiateDelegateWhitelist[] = - "auth-negotiate-delegate-whitelist"; - -} // namespace switches - -} // namespace brightray diff --git a/brightray/common/switches.h b/brightray/common/switches.h deleted file mode 100644 index 3af00813830f7..0000000000000 --- a/brightray/common/switches.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2016 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef BRIGHTRAY_COMMON_SWITCHES_H_ -#define BRIGHTRAY_COMMON_SWITCHES_H_ - -namespace brightray { - -namespace switches { - -extern const char kHostRules[]; -extern const char kNoProxyServer[]; -extern const char kProxyServer[]; -extern const char kProxyBypassList[]; -extern const char kProxyPacUrl[]; -extern const char kDisableHttp2[]; -extern const char kAuthServerWhitelist[]; -extern const char kAuthNegotiateDelegateWhitelist[]; - -} // namespace switches - -} // namespace brightray - -#endif // BRIGHTRAY_COMMON_SWITCHES_H_ diff --git a/brightray/filenames.gypi b/brightray/filenames.gypi index 03b1106f978cb..ac1f8eb8e654e 100644 --- a/brightray/filenames.gypi +++ b/brightray/filenames.gypi @@ -4,8 +4,6 @@ 'browser/brightray_paths.h', 'browser/browser_client.cc', 'browser/browser_client.h', - 'browser/browser_context.cc', - 'browser/browser_context.h', 'browser/browser_main_parts.cc', 'browser/browser_main_parts.h', 'browser/browser_main_parts_mac.mm', @@ -29,8 +27,6 @@ 'browser/inspectable_web_contents_view.h', 'browser/inspectable_web_contents_view_mac.h', 'browser/inspectable_web_contents_view_mac.mm', - 'browser/io_thread.cc', - 'browser/io_thread.h', 'browser/mac/bry_inspectable_web_contents_view.h', 'browser/mac/bry_inspectable_web_contents_view.mm', 'browser/mac/cocoa_notification.h', @@ -49,8 +45,6 @@ 'browser/media/media_stream_devices_controller.h', 'browser/net/require_ct_delegate.cc', 'browser/net/require_ct_delegate.h', - 'browser/net_log.cc', - 'browser/net_log.h', 'browser/notification_delegate.h', 'browser/notification_presenter.cc', 'browser/notification_presenter.h', @@ -81,8 +75,6 @@ 'browser/win/windows_toast_notification.h', 'browser/special_storage_policy.cc', 'browser/special_storage_policy.h', - 'browser/url_request_context_getter.cc', - 'browser/url_request_context_getter.h', 'browser/views/inspectable_web_contents_view_views.h', 'browser/views/inspectable_web_contents_view_views.cc', 'browser/views/views_delegate.cc', @@ -102,8 +94,6 @@ 'common/main_delegate.cc', 'common/main_delegate.h', 'common/main_delegate_mac.mm', - 'common/switches.cc', - 'common/switches.h', 'common/platform_util_linux.cc', 'common/platform_util.h', ], diff --git a/docs/api/net-log.md b/docs/api/net-log.md index 5e82a83a14d1a..fb6dd3e0b0391 100644 --- a/docs/api/net-log.md +++ b/docs/api/net-log.md @@ -1,21 +1,26 @@ # netLog -> Logging network events. +> Logging network events for a session. Process: [Main](../glossary.md#main-process) ```javascript -const {netLog} = require('electron') -console.log('Start recording net-logs') -netLog.startLogging('/path/to/net-log') -// After some network events -netLog.stopLogging(path => { - console.log('Net-logs written to', path) +const { netLog } = require('electron') + +app.on('ready', function () { + netLog.startLogging('/path/to/net-log') + // After some network events + netLog.stopLogging(path => { + console.log('Net-logs written to', path) + }) }) ``` See [`--log-net-log`](chrome-command-line-switches.md#--log-net-logpath) to log network events throughout the app's lifecycle. +**Note:** All methods unless specified can only be used after the `ready` event +of the `app` module gets emitted. + ## Methods ### `netLog.startLogging(path)` diff --git a/docs/api/session.md b/docs/api/session.md index 0d3c66acad596..87aa7b0f3df4f 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -426,3 +426,20 @@ app.on('ready', function () { }) }) ``` + +#### `ses.netLog` + +A [NetLog](net-log.md) object for this session. + +```javascript +const { app, session } = require('electron') + +app.on('ready', function () { + const netLog = session.fromPartition('some-partition').netLog + netLog.startLogging('/path/to/net-log') + // After some network events + netLog.stopLogging(path => { + console.log('Net-logs written to', path) + }) +}) +``` diff --git a/filenames.gypi b/filenames.gypi index 9aa6f5ea335bd..fd90119491fe8 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -230,6 +230,10 @@ 'atom/browser/common_web_contents_delegate_views.cc', 'atom/browser/common_web_contents_delegate.cc', 'atom/browser/common_web_contents_delegate.h', + 'atom/browser/cookie_change_notifier.cc', + 'atom/browser/cookie_change_notifier.h', + 'atom/browser/io_thread.cc', + 'atom/browser/io_thread.h', 'atom/browser/javascript_environment.cc', 'atom/browser/javascript_environment.h', 'atom/browser/lib/bluetooth_chooser.cc', @@ -285,20 +289,26 @@ 'atom/browser/net/http_protocol_handler.h', 'atom/browser/net/js_asker.cc', 'atom/browser/net/js_asker.h', + 'atom/browser/net/resolve_proxy_helper.cc', + 'atom/browser/net/resolve_proxy_helper.h', 'atom/browser/net/url_request_about_job.cc', 'atom/browser/net/url_request_about_job.h', 'atom/browser/net/url_request_async_asar_job.cc', 'atom/browser/net/url_request_async_asar_job.h', - 'atom/browser/net/url_request_string_job.cc', - 'atom/browser/net/url_request_string_job.h', 'atom/browser/net/url_request_buffer_job.cc', 'atom/browser/net/url_request_buffer_job.h', + 'atom/browser/net/url_request_context_getter.cc', + 'atom/browser/net/url_request_context_getter.h', 'atom/browser/net/url_request_fetch_job.cc', 'atom/browser/net/url_request_fetch_job.h', 'atom/browser/net/url_request_stream_job.cc', 'atom/browser/net/url_request_stream_job.h', + 'atom/browser/net/url_request_string_job.cc', + 'atom/browser/net/url_request_string_job.h', 'atom/browser/node_debugger.cc', 'atom/browser/node_debugger.h', + 'atom/browser/pref_store_delegate.cc', + 'atom/browser/pref_store_delegate.h', 'atom/browser/relauncher_linux.cc', 'atom/browser/relauncher_mac.cc', 'atom/browser/relauncher_win.cc', @@ -306,8 +316,6 @@ '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', diff --git a/lib/browser/api/net-log.js b/lib/browser/api/net-log.js index 09d5244fc2da0..1649c6332a26a 100644 --- a/lib/browser/api/net-log.js +++ b/lib/browser/api/net-log.js @@ -1,16 +1,28 @@ 'use strict' -const {netLog, NetLog} = process.atomBinding('net_log') +// TODO(deepak1556): Deprecate and remove standalone netLog module, +// it is now a property of sessio module. +const { app, session } = require('electron') -NetLog.prototype.stopLogging = function (callback) { - if (callback && typeof callback !== 'function') { - throw new Error('Invalid callback function') - } +// Fallback to default session. +Object.setPrototypeOf(module.exports, new Proxy({}, { + get (target, property) { + if (!app.isReady()) return + + const netLog = session.defaultSession.netLog + if (!Object.getPrototypeOf(netLog).hasOwnProperty(property)) return + + // Returning a native function directly would throw error. + return (...args) => netLog[property](...args) + }, - const path = this.currentlyLoggingPath - this._stopLogging(() => { - if (callback) callback(path) - }) -} + ownKeys () { + if (!app.isReady()) return [] -module.exports = netLog + return Object.getOwnPropertyNames(Object.getPrototypeOf(session.defaultSession.netLog)) + }, + + getOwnPropertyDescriptor (target) { + return { configurable: true, enumerable: true } + } +})) diff --git a/spec/api-net-log-spec.js b/spec/api-net-log-spec.js index 1e9ca66722dc2..d7d81858fb70e 100644 --- a/spec/api-net-log-spec.js +++ b/spec/api-net-log-spec.js @@ -4,13 +4,14 @@ const fs = require('fs') const os = require('os') const path = require('path') const ChildProcess = require('child_process') -const {remote} = require('electron') -const {netLog} = remote +const { remote } = require('electron') +const { session } = remote const appPath = path.join(__dirname, 'fixtures', 'api', 'net-log') const dumpFile = path.join(os.tmpdir(), 'net_log.json') const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json') const isCI = remote.getGlobal('isCi') +const netLog = session.fromPartition('net-log').netLog describe('netLog module', () => { let server @@ -45,8 +46,12 @@ describe('netLog module', () => { afterEach(() => { try { - fs.unlinkSync(dumpFile) - fs.unlinkSync(dumpFileDynamic) + if (fs.existsSync(dumpFile)) { + fs.unlinkSync(dumpFile) + } + if (fs.existsSync(dumpFileDynamic)) { + fs.unlinkSync(dumpFileDynamic) + } } catch (e) { // Ignore error } @@ -87,22 +92,21 @@ describe('netLog module', () => { }) }) - // The following tests are skipped on Linux CI - - it('should begin and end logging automatically when --log-net-log is passed', (done) => { + it('should begin and end logging automatically when --log-net-log is passed', done => { if (isCI && process.platform === 'linux') { done() return } - let appProcess = ChildProcess.spawn(remote.process.execPath, - [appPath, `--log-net-log=${dumpFile}`], { + const appProcess = ChildProcess.spawn(remote.process.execPath, + [appPath], { env: { - TEST_REQUEST_URL: server.url + TEST_REQUEST_URL: server.url, + TEST_DUMP_FILE: dumpFile } }) - appProcess.once('exit', () => { + appProcess.once('close', () => { assert(fs.existsSync(dumpFile)) done() }) @@ -114,20 +118,17 @@ describe('netLog module', () => { return } - let appProcess = ChildProcess.spawn(remote.process.execPath, - [appPath, `--log-net-log=${dumpFile}`], { + const appProcess = ChildProcess.spawn(remote.process.execPath, + [appPath], { env: { TEST_REQUEST_URL: server.url, - TEST_DUMP_FILE: dumpFileDynamic, + TEST_DUMP_FILE: dumpFile, + TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic, TEST_MANUAL_STOP: true } }) - appProcess.stdout.on('data', (data) => { - console.log(data.toString()) - }) - - appProcess.once('exit', () => { + appProcess.once('close', () => { assert(fs.existsSync(dumpFile)) assert(fs.existsSync(dumpFileDynamic)) done() @@ -144,11 +145,11 @@ describe('netLog module', () => { [appPath], { env: { TEST_REQUEST_URL: server.url, - TEST_DUMP_FILE: dumpFileDynamic + TEST_DUMP_FILE_DYNAMIC: dumpFileDynamic } }) - appProcess.once('exit', () => { + appProcess.once('close', () => { assert(fs.existsSync(dumpFileDynamic)) done() }) diff --git a/spec/api-session-spec.js b/spec/api-session-spec.js index 7ac14e1f1f885..0ab5d1ec15791 100644 --- a/spec/api-session-spec.js +++ b/spec/api-session-spec.js @@ -471,24 +471,63 @@ describe('session module', () => { }) describe('ses.setProxy(options, callback)', () => { + let server = null + let customSession = null + + beforeEach(() => { + customSession = session.fromPartition('proxyconfig') + }) + + afterEach(() => { + if (server) { + server.close() + } + if (customSession) { + customSession.destroy() + } + }) + it('allows configuring proxy settings', (done) => { - const config = {proxyRules: 'http=myproxy:80'} - session.defaultSession.setProxy(config, () => { - session.defaultSession.resolveProxy('http://localhost', (proxy) => { - assert.equal(proxy, 'PROXY myproxy:80') + const config = { proxyRules: 'http=myproxy:80' } + customSession.setProxy(config, () => { + customSession.resolveProxy('http://localhost', (proxy) => { + assert.strictEqual(proxy, 'PROXY myproxy:80') done() }) }) }) + it('allows configuring proxy settings with pacScript', (done) => { + server = http.createServer((req, res) => { + const pac = ` + function FindProxyForURL(url, host) { + return "PROXY myproxy:8132"; + } + ` + res.writeHead(200, { + 'Content-Type': 'application/x-ns-proxy-autoconfig' + }) + res.end(pac) + }) + server.listen(0, '127.0.0.1', () => { + const config = { pacScript: `http://127.0.0.1:${server.address().port}` } + customSession.setProxy(config, () => { + customSession.resolveProxy('http://localhost', (proxy) => { + assert.strictEqual(proxy, 'PROXY myproxy:8132') + done() + }) + }) + }) + }) + it('allows bypassing proxy settings', (done) => { const config = { proxyRules: 'http=myproxy:80', proxyBypassRules: '' } - session.defaultSession.setProxy(config, () => { - session.defaultSession.resolveProxy('http://localhost', (proxy) => { - assert.equal(proxy, 'DIRECT') + customSession.setProxy(config, () => { + customSession.resolveProxy('http://localhost', (proxy) => { + assert.strictEqual(proxy, 'DIRECT') done() }) }) diff --git a/spec/fixtures/api/net-log/main.js b/spec/fixtures/api/net-log/main.js index 54fa53965cddb..d14671d939a66 100644 --- a/spec/fixtures/api/net-log/main.js +++ b/spec/fixtures/api/net-log/main.js @@ -1,4 +1,8 @@ -const {app, net, netLog} = require('electron') +const { app, net, session } = require('electron') + +if (process.env.TEST_DUMP_FILE) { + app.commandLine.appendSwitch('log-net-log', process.env.TEST_DUMP_FILE) +} function request () { return new Promise((resolve) => { @@ -10,24 +14,33 @@ function request () { }) } -function stopLogging () { +function stopLogging (netLog) { return new Promise((resolve) => { - netLog.stopLogging(() => { + netLog.stopLogging((path) => { resolve() }) }) } app.on('ready', async () => { - if (process.env.TEST_DUMP_FILE) { - netLog.startLogging(process.env.TEST_DUMP_FILE) - } + const netLog = session.defaultSession.netLog - await request() + // The net log exporter becomes ready only after + // default path is setup, which is posted as task + // to a sequenced task runner due to sync IO operations, + // the task are blocked for some reason, + // revisit task scheduling after 69 upgrade and fix this workaround. + setImmediate(async () => { + if (process.env.TEST_DUMP_FILE_DYNAMIC) { + netLog.startLogging(process.env.TEST_DUMP_FILE_DYNAMIC) + } - if (process.env.TEST_MANUAL_STOP) { - await stopLogging() - } + await request() - app.quit() + if (process.env.TEST_MANUAL_STOP) { + await stopLogging(netLog) + } + + app.quit() + }) }) diff --git a/vendor/libchromiumcontent b/vendor/libchromiumcontent index d9e39391cfae4..ccf1e2dd1dd2e 160000 --- a/vendor/libchromiumcontent +++ b/vendor/libchromiumcontent @@ -1 +1 @@ -Subproject commit d9e39391cfae447a84e276a402342cf8b4b5bcba +Subproject commit ccf1e2dd1dd2e12125dbbdb98b2cc51142cd07b9