Compare commits

...

2 Commits

Author SHA1 Message Date
Shelley Vohr
bc070f6707 chore: throw in utility net before app is ready 2024-03-23 21:21:45 +01:00
Shelley Vohr
63411ec513 fix: UtilityProcess.fork before app ready 2024-03-22 14:11:27 +01:00
10 changed files with 75 additions and 25 deletions

View File

@@ -1,11 +1,20 @@
import { app } from 'electron/main';
import { IncomingMessage } from 'electron/utility';
import type { ClientRequestConstructorOptions } from 'electron/utility';
import { ClientRequest } from '@electron/internal/common/api/net-client-request';
import { fetchWithSession } from '@electron/internal/browser/api/net-fetch';
const { isOnline, resolveHost } = process._linkedBinding('electron_common_net');
const { _ensureNetworkServiceInitialized } = process._linkedBinding('electron_browser_utility_process');
if (app.isReady()) {
_ensureNetworkServiceInitialized();
}
export function request (options: ClientRequestConstructorOptions | string, callback?: (message: IncomingMessage) => void) {
if (!app.isReady()) {
throw new Error('net module can only be used after app is ready');
}
return new ClientRequest(options, callback);
}

View File

@@ -194,22 +194,6 @@ UtilityProcessWrapper::UtilityProcessWrapper(
connector_->set_connection_error_handler(base::BindOnce(
&UtilityProcessWrapper::CloseConnectorPort, weak_factory_.GetWeakPtr()));
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory;
network::mojom::URLLoaderFactoryParamsPtr loader_params =
network::mojom::URLLoaderFactoryParams::New();
loader_params->process_id = pid_;
loader_params->is_orb_enabled = false;
loader_params->is_trusted = true;
network::mojom::NetworkContext* network_context =
g_browser_process->system_network_context_manager()->GetContext();
network_context->CreateURLLoaderFactory(
url_loader_factory.InitWithNewPipeAndPassReceiver(),
std::move(loader_params));
params->url_loader_factory = std::move(url_loader_factory);
mojo::PendingRemote<network::mojom::HostResolver> host_resolver;
network_context->CreateHostResolver(
{}, host_resolver.InitWithNewPipeAndPassReceiver());
params->host_resolver = std::move(host_resolver);
node_service_remote_->Initialize(std::move(params));
}
@@ -250,6 +234,30 @@ void UtilityProcessWrapper::CloseConnectorPort() {
}
}
void UtilityProcessWrapper::EnsureNetworkServiceInitialized() {
if (network_context_initialized_)
return;
network_context_initialized_ = true;
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory;
network::mojom::URLLoaderFactoryParamsPtr loader_params =
network::mojom::URLLoaderFactoryParams::New();
loader_params->process_id = pid_;
loader_params->is_orb_enabled = false;
loader_params->is_trusted = true;
network::mojom::NetworkContext* network_context =
g_browser_process->system_network_context_manager()->GetContext();
network_context->CreateURLLoaderFactory(
url_loader_factory.InitWithNewPipeAndPassReceiver(),
std::move(loader_params));
mojo::PendingRemote<network::mojom::HostResolver> host_resolver;
network_context->CreateHostResolver(
{}, host_resolver.InitWithNewPipeAndPassReceiver());
node_service_remote_->InitializeNetworkService(std::move(url_loader_factory),
std::move(host_resolver));
}
void UtilityProcessWrapper::Shutdown(int exit_code) {
if (pid_ != base::kNullProcessId)
GetAllUtilityProcessWrappers().Remove(pid_);
@@ -431,6 +439,9 @@ void Initialize(v8::Local<v8::Object> exports,
v8::Isolate* isolate = context->GetIsolate();
gin_helper::Dictionary dict(isolate, exports);
dict.SetMethod("_fork", &electron::api::UtilityProcessWrapper::Create);
dict.SetMethod(
"_ensureNetworkServiceInitialized",
&electron::api::UtilityProcessWrapper::EnsureNetworkServiceInitialized);
}
} // namespace

View File

@@ -48,6 +48,7 @@ class UtilityProcessWrapper
static raw_ptr<UtilityProcessWrapper> FromProcessId(base::ProcessId pid);
void Shutdown(int exit_code);
void EnsureNetworkServiceInitialized();
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
@@ -84,6 +85,7 @@ class UtilityProcessWrapper
int stdout_read_fd_ = -1;
int stderr_read_fd_ = -1;
bool connector_closed_ = false;
bool network_context_initialized_ = false;
std::unique_ptr<mojo::Connector> connector_;
blink::MessagePortDescriptor host_port_;
mojo::Remote<node::mojom::NodeService> node_service_remote_;

View File

@@ -126,7 +126,7 @@ void BrowserProcessImpl::PreCreateThreads() {
// Must be created before the IOThread.
// Once IOThread class is no longer needed,
// this can be created on first use.
if (!SystemNetworkContextManager::GetInstance())
if (!SystemNetworkContextManager::HasInstance())
SystemNetworkContextManager::CreateInstance(local_state_.get());
}

View File

@@ -999,6 +999,10 @@ void ElectronBrowserClient::OnNetworkServiceCreated(
if (!g_browser_process)
return;
if (!SystemNetworkContextManager::HasInstance())
SystemNetworkContextManager::CreateInstance(
g_browser_process->local_state());
g_browser_process->system_network_context_manager()->OnNetworkServiceCreated(
network_service);
}

View File

@@ -214,8 +214,21 @@ SystemNetworkContextManager* SystemNetworkContextManager::CreateInstance(
return g_system_network_context_manager;
}
// static
bool SystemNetworkContextManager::HasInstance() {
return !!g_system_network_context_manager;
}
// static
SystemNetworkContextManager* SystemNetworkContextManager::GetInstance() {
if (!g_system_network_context_manager) {
// Initialize the network service, which will trigger
// ElectronBrowserClient::OnNetworkServiceCreated(), which calls
// CreateInstance() to initialize |g_system_network_context_manager|.
content::GetNetworkService();
DCHECK(g_system_network_context_manager);
}
return g_system_network_context_manager;
}
@@ -223,6 +236,7 @@ SystemNetworkContextManager* SystemNetworkContextManager::GetInstance() {
void SystemNetworkContextManager::DeleteInstance() {
DCHECK(g_system_network_context_manager);
delete g_system_network_context_manager;
g_system_network_context_manager = nullptr;
}
// c.f.

View File

@@ -41,11 +41,16 @@ class SystemNetworkContextManager {
SystemNetworkContextManager& operator=(const SystemNetworkContextManager&) =
delete;
// Checks if the global SystemNetworkContextManager has been created.
static bool HasInstance();
// Creates the global instance of SystemNetworkContextManager. If an
// instance already exists, this will cause a DCHECK failure.
static SystemNetworkContextManager* CreateInstance(PrefService* pref_service);
// Gets the global SystemNetworkContextManager instance.
// Gets the global SystemNetworkContextManager instance. If it has not been
// created yet, NetworkService is called, which will cause the
// SystemNetworkContextManager to be created.
static SystemNetworkContextManager* GetInstance();
// Destroys the global SystemNetworkContextManager instance.

View File

@@ -68,16 +68,19 @@ NodeService::~NodeService() {
}
}
void NodeService::InitializeNetworkService(
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
mojo::PendingRemote<network::mojom::HostResolver> host_resolver) {
URLLoaderBundle::GetInstance()->SetURLLoaderFactory(
std::move(url_loader_factory), mojo::Remote(std::move(host_resolver)));
}
void NodeService::Initialize(node::mojom::NodeServiceParamsPtr params) {
if (NodeBindings::IsInitialized())
return;
ParentPort::GetInstance()->Initialize(std::move(params->port));
URLLoaderBundle::GetInstance()->SetURLLoaderFactory(
std::move(params->url_loader_factory),
mojo::Remote(std::move(params->host_resolver)));
js_env_ = std::make_unique<JavascriptEnvironment>(node_bindings_->uv_loop());
v8::HandleScope scope(js_env_->isolate());

View File

@@ -57,8 +57,11 @@ class NodeService : public node::mojom::NodeService {
NodeService(const NodeService&) = delete;
NodeService& operator=(const NodeService&) = delete;
// mojom::NodeService implementation:
// mojom::NodeService:
void Initialize(node::mojom::NodeServiceParamsPtr params) override;
void InitializeNetworkService(
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory,
mojo::PendingRemote<network::mojom::HostResolver> host_resolver) override;
private:
// This needs to be initialized first so that it can be destroyed last

View File

@@ -15,11 +15,10 @@ struct NodeServiceParams {
array<string> args;
array<string> exec_args;
blink.mojom.MessagePortDescriptor port;
pending_remote<network.mojom.URLLoaderFactory> url_loader_factory;
pending_remote<network.mojom.HostResolver> host_resolver;
};
[ServiceSandbox=sandbox.mojom.Sandbox.kNoSandbox]
interface NodeService {
Initialize(NodeServiceParams params);
InitializeNetworkService(pending_remote<network.mojom.URLLoaderFactory> url_loader_factory, pending_remote<network.mojom.HostResolver> host_resolver);
};