Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ electron objects that extend gin::Wrappable and gets
allocated on the cpp heap

diff --git a/gin/public/wrappable_pointer_tags.h b/gin/public/wrappable_pointer_tags.h
index 573bcb2e56068a2ade6d8ab28964b077487874fd..93bf3814b38f8093e39f1a0548a43dfb347e49b3 100644
index 573bcb2e56068a2ade6d8ab28964b077487874fd..0321ca6d3c7e1ed541cc1beffb20b1db3d03a0c8 100644
--- a/gin/public/wrappable_pointer_tags.h
+++ b/gin/public/wrappable_pointer_tags.h
@@ -74,7 +74,13 @@ enum WrappablePointerTag : uint16_t {
@@ -74,7 +74,14 @@ enum WrappablePointerTag : uint16_t {
kTextInputControllerBindings, // content::TextInputControllerBindings
kWebAXObjectProxy, // content::WebAXObjectProxy
kWrappedExceptionHandler, // extensions::WrappedExceptionHandler
Expand All @@ -22,7 +22,8 @@ index 573bcb2e56068a2ade6d8ab28964b077487874fd..93bf3814b38f8093e39f1a0548a43dfb
+ kElectronMenu, // electron::api::Menu
+ kElectronNetLog, // electron::api::NetLog
+ kElectronSession, // electron::api::Session
+ kLastPointerTag = kElectronSession,
+ kElectronWebRequest, // electron::api::WebRequest
+ kLastPointerTag = kElectronWebRequest,
};

static_assert(kLastPointerTag <
10 changes: 4 additions & 6 deletions shell/browser/api/electron_api_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1360,12 +1360,10 @@ v8::Local<v8::Value> Session::ServiceWorkerContext(v8::Isolate* isolate) {
return service_worker_context_.Get(isolate);
}

v8::Local<v8::Value> Session::WebRequest(v8::Isolate* isolate) {
if (web_request_.IsEmptyThreadSafe()) {
auto handle = WebRequest::Create(base::PassKey<Session>{}, isolate);
web_request_.Reset(isolate, handle.ToV8());
}
return web_request_.Get(isolate);
WebRequest* Session::WebRequest(v8::Isolate* isolate) {
if (!web_request_)
web_request_ = WebRequest::Create(isolate, base::PassKey<Session>{});
return web_request_;
}

NetLog* Session::NetLog(v8::Isolate* isolate) {
Expand Down
5 changes: 3 additions & 2 deletions shell/browser/api/electron_api_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct PreloadScript;
namespace api {

class NetLog;
class WebRequest;

class Session final : public gin::Wrappable<Session>,
public gin_helper::Constructible<Session>,
Expand Down Expand Up @@ -169,7 +170,7 @@ class Session final : public gin::Wrappable<Session>,
v8::Local<v8::Value> Extensions(v8::Isolate* isolate);
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
v8::Local<v8::Value> ServiceWorkerContext(v8::Isolate* isolate);
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
WebRequest* WebRequest(v8::Isolate* isolate);
api::NetLog* NetLog(v8::Isolate* isolate);
void Preconnect(const gin_helper::Dictionary& options, gin::Arguments* args);
v8::Local<v8::Promise> CloseAllConnections();
Expand Down Expand Up @@ -217,7 +218,7 @@ class Session final : public gin::Wrappable<Session>,
v8::TracedReference<v8::Value> protocol_;
cppgc::Member<api::NetLog> net_log_;
v8::TracedReference<v8::Value> service_worker_context_;
v8::TracedReference<v8::Value> web_request_;
cppgc::Member<api::WebRequest> web_request_;

raw_ptr<v8::Isolate> isolate_;

Expand Down
47 changes: 26 additions & 21 deletions shell/browser/api/electron_api_web_request.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "gin/converter.h"
#include "gin/dictionary.h"
#include "gin/object_template_builder.h"
#include "gin/persistent.h"
#include "shell/browser/api/electron_api_session.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/api/electron_api_web_frame_main.h"
Expand Down Expand Up @@ -204,7 +205,8 @@ CalculateOnBeforeSendHeadersDelta(const net::HttpRequestHeaders* old_headers,

} // namespace

gin::DeprecatedWrapperInfo WebRequest::kWrapperInfo = {gin::kEmbedderNativeGin};
const gin::WrapperInfo WebRequest::kWrapperInfo = {{gin::kEmbedderNativeGin},
gin::kElectronWebRequest};

WebRequest::RequestFilter::RequestFilter(
std::set<URLPattern> include_url_patterns,
Expand Down Expand Up @@ -318,8 +320,7 @@ WebRequest::~WebRequest() = default;

gin::ObjectTemplateBuilder WebRequest::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin_helper::DeprecatedWrappable<WebRequest>::GetObjectTemplateBuilder(
isolate)
return gin::Wrappable<WebRequest>::GetObjectTemplateBuilder(isolate)
.SetMethod(
"onBeforeRequest",
&WebRequest::SetResponseListener<ResponseEvent::kOnBeforeRequest>)
Expand All @@ -342,8 +343,16 @@ gin::ObjectTemplateBuilder WebRequest::GetObjectTemplateBuilder(
&WebRequest::SetSimpleListener<SimpleEvent::kOnCompleted>);
}

const char* WebRequest::GetTypeName() {
return GetClassName();
const gin::WrapperInfo* WebRequest::wrapper_info() const {
return &kWrapperInfo;
}

const char* WebRequest::GetHumanReadableName() const {
return "Electron / WebRequest";
}

void WebRequest::Trace(cppgc::Visitor* visitor) const {
gin::Wrappable<WebRequest>::Trace(visitor);
}

bool WebRequest::HasListener() const {
Expand Down Expand Up @@ -381,9 +390,11 @@ int WebRequest::HandleOnBeforeRequestResponseEvent(
gin_helper::Dictionary details(isolate, v8::Object::New(isolate));
FillDetails(&details, request_info, request, *new_url);

ResponseCallback response =
base::BindOnce(&WebRequest::OnBeforeRequestListenerResult,
base::Unretained(this), request_info->id);
auto& allocation_handle = isolate->GetCppHeap()->GetAllocationHandle();
ResponseCallback response = base::BindOnce(
&WebRequest::OnBeforeRequestListenerResult,
gin::WrapPersistent(weak_factory_.GetWeakCell(allocation_handle)),
request_info->id);
info.listener.Run(gin::ConvertToV8(isolate, details), std::move(response));
return net::ERR_IO_PENDING;
}
Expand Down Expand Up @@ -777,22 +788,16 @@ void WebRequest::OnLoginAuthResult(
}

// static
gin_helper::Handle<WebRequest> WebRequest::FromOrCreate(
v8::Isolate* isolate,
content::BrowserContext* browser_context) {
v8::Local<v8::Value> web_request =
Session::FromOrCreate(isolate, browser_context)->WebRequest(isolate);
gin_helper::Handle<WebRequest> handle;
gin::ConvertFromV8(isolate, web_request, &handle);
DCHECK(!handle.IsEmpty());
return handle;
WebRequest* WebRequest::FromOrCreate(v8::Isolate* isolate,
content::BrowserContext* browser_context) {
return Session::FromOrCreate(isolate, browser_context)->WebRequest(isolate);
}

// static
gin_helper::Handle<WebRequest> WebRequest::Create(
base::PassKey<Session> passkey,
v8::Isolate* isolate) {
return gin_helper::CreateHandle(isolate, new WebRequest{std::move(passkey)});
WebRequest* WebRequest::Create(v8::Isolate* isolate,
base::PassKey<Session> passkey) {
return cppgc::MakeGarbageCollected<WebRequest>(
isolate->GetCppHeap()->GetAllocationHandle(), std::move(passkey));
}

} // namespace electron::api
34 changes: 21 additions & 13 deletions shell/browser/api/electron_api_web_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
#include <string>

#include "base/types/pass_key.h"
#include "gin/weak_cell.h"
#include "gin/wrappable.h"
#include "net/base/completion_once_callback.h"
#include "services/network/public/cpp/resource_request.h"
#include "shell/common/gin_helper/wrappable.h"

class URLPattern;

Expand All @@ -38,7 +39,7 @@ namespace electron::api {

class Session;

class WebRequest final : public gin_helper::DeprecatedWrappable<WebRequest> {
class WebRequest final : public gin::Wrappable<WebRequest> {
public:
using BeforeSendHeadersCallback =
base::OnceCallback<void(const std::set<std::string>& removed_headers,
Expand All @@ -65,21 +66,29 @@ class WebRequest final : public gin_helper::DeprecatedWrappable<WebRequest> {
// Convenience wrapper around api::Session::FromOrCreate()->WebRequest().
// Creates the Session and WebRequest if they don't already exist.
// Note that the WebRequest is owned by the session, not by the caller.
static gin_helper::Handle<WebRequest> FromOrCreate(
v8::Isolate* isolate,
content::BrowserContext* browser_context);
static WebRequest* FromOrCreate(v8::Isolate* isolate,
content::BrowserContext* browser_context);

// Return a new WebRequest object. This can only be called by api::Session.
static gin_helper::Handle<WebRequest> Create(base::PassKey<Session>,
v8::Isolate* isolate);
static WebRequest* Create(v8::Isolate* isolate, base::PassKey<Session>);

// Make public for cppgc::MakeGarbageCollected.
explicit WebRequest(base::PassKey<Session>);
~WebRequest() override;

// disable copy
WebRequest(const WebRequest&) = delete;
WebRequest& operator=(const WebRequest&) = delete;

static const char* GetClassName() { return "WebRequest"; }

// gin_helper::Wrappable:
static gin::DeprecatedWrapperInfo kWrapperInfo;
// gin::Wrappable:
static const gin::WrapperInfo kWrapperInfo;
void Trace(cppgc::Visitor*) const override;
const gin::WrapperInfo* wrapper_info() const override;
const char* GetHumanReadableName() const override;
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
const char* GetTypeName() override;

bool HasListener() const;
int OnBeforeRequest(extensions::WebRequestInfo* info,
Expand Down Expand Up @@ -118,9 +127,6 @@ class WebRequest final : public gin_helper::DeprecatedWrappable<WebRequest> {
void OnRequestWillBeDestroyed(extensions::WebRequestInfo* info);

private:
explicit WebRequest(base::PassKey<Session>);
~WebRequest() override;

// Contains info about requests that are blocked waiting for a response from
// the user.
struct BlockedRequest;
Expand Down Expand Up @@ -235,6 +241,8 @@ class WebRequest final : public gin_helper::DeprecatedWrappable<WebRequest> {
std::map<SimpleEvent, SimpleListenerInfo> simple_listeners_;
std::map<ResponseEvent, ResponseListenerInfo> response_listeners_;
std::map<uint64_t, BlockedRequest> blocked_requests_;

gin::WeakCellFactory<WebRequest> weak_factory_{this};
};

} // namespace electron::api
Expand Down
30 changes: 18 additions & 12 deletions shell/browser/electron_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1272,11 +1272,11 @@ bool ElectronBrowserClient::WillInterceptWebSocket(
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
auto* browser_context = frame->GetProcess()->GetBrowserContext();
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
auto* web_request = api::WebRequest::FromOrCreate(isolate, browser_context);

// NOTE: Some unit test environments do not initialize
// BrowserContextKeyedAPI factories for e.g. WebRequest.
if (!web_request.get())
if (!web_request)
return false;

bool has_listener = web_request->HasListener();
Expand Down Expand Up @@ -1304,8 +1304,8 @@ void ElectronBrowserClient::CreateWebSocket(
v8::HandleScope scope(isolate);
auto* browser_context = frame->GetProcess()->GetBrowserContext();

auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
DCHECK(web_request.get());
auto* web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
DCHECK(web_request);

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
if (!web_request->HasListener()) {
Expand All @@ -1322,7 +1322,7 @@ void ElectronBrowserClient::CreateWebSocket(
#endif

ProxyingWebSocket::StartProxying(
web_request.get(), std::move(factory), url, site_for_cookies, user_agent,
web_request, std::move(factory), url, site_for_cookies, user_agent,
std::move(handshake_client), true, frame->GetProcess()->GetDeprecatedID(),
frame->GetRoutingID(), frame->GetLastCommittedOrigin(), browser_context,
&next_id_);
Expand All @@ -1346,8 +1346,9 @@ void ElectronBrowserClient::WillCreateURLLoaderFactory(
scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope scope(isolate);
auto web_request = api::WebRequest::FromOrCreate(isolate, browser_context);
DCHECK(web_request.get());
auto* const web_request =
api::WebRequest::FromOrCreate(isolate, browser_context);
DCHECK(web_request);

#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
if (!web_request->HasListener()) {
Expand Down Expand Up @@ -1388,13 +1389,18 @@ void ElectronBrowserClient::WillCreateURLLoaderFactory(

auto* protocol_registry =
ProtocolRegistry::FromBrowserContext(browser_context);
new ProxyingURLLoaderFactory(
web_request.get(), protocol_registry->intercept_handlers(),
new ProxyingURLLoaderFactory{
web_request,
protocol_registry->intercept_handlers(),
render_process_id,
frame_host ? frame_host->GetRoutingID() : IPC::mojom::kRoutingIdNone,
&next_id_, std::move(navigation_ui_data), std::move(navigation_id),
std::move(proxied_receiver), std::move(target_factory_remote),
std::move(header_client_receiver), type);
&next_id_,
std::move(navigation_ui_data),
std::move(navigation_id),
std::move(proxied_receiver),
std::move(target_factory_remote),
std::move(header_client_receiver),
type};
}

std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
Expand Down
Loading
Loading