#include "extensions/renderer/api/web_request_hooks.h"
#include "base/logging.h"
#include "base/values.h"
#include "content/public/renderer/v8_value_converter.h"
#include "extensions/common/api/web_request.h"
#include "extensions/common/extension_api.h"
#include "extensions/renderer/bindings/api_binding_hooks.h"
#include "extensions/renderer/bindings/js_runner.h"
#include "extensions/renderer/get_script_context.h"
#include "extensions/renderer/module_system.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/script_context_set.h"
#include "gin/converter.h"
#include "v8/include/v8-context.h"
#include "v8/include/v8-exception.h"
#include "v8/include/v8-function.h"
#include "v8/include/v8-object.h"
namespace extensions {
WebRequestHooks::WebRequestHooks() = default;
WebRequestHooks::~WebRequestHooks() = default;
bool WebRequestHooks::CreateCustomEvent(v8::Local<v8::Context> context,
const std::string& event_name,
v8::Local<v8::Value>* event_out) {
if (event_name == api::web_request::OnActionIgnored::kEventName)
return false;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
ScriptContext* script_context = GetScriptContextFromV8Context(context);
v8::Local<v8::Object> internal_bindings;
{
ModuleSystem::NativesEnabledScope enable_natives(
script_context->module_system());
if (!script_context->module_system()
->Require("webRequestEvent")
.ToLocal(&internal_bindings)) {
return true;
}
}
v8::Local<v8::Value> get_event_value;
{
v8::TryCatch try_catch(isolate);
if (!internal_bindings
->Get(context,
gin::StringToSymbol(isolate, "createWebRequestEvent"))
.ToLocal(&get_event_value) ||
!get_event_value->IsFunction()) {
LOG(ERROR) << "Unexpected error when creating custom webRequest event: "
<< "`createWebRequestEvent` not found on internal bindings.";
return true;
}
}
const base::Value::Dict* event_spec =
ExtensionAPI::GetSharedInstance()->GetSchema(event_name);
DCHECK(event_spec);
const base::Value::List* extra_params =
event_spec->FindList("extraParameters");
CHECK(extra_params);
v8::Local<v8::Value> extra_parameters_spec =
content::V8ValueConverter::Create()->ToV8Value(*extra_params, context);
v8::Local<v8::Function> get_event = get_event_value.As<v8::Function>();
v8::Local<v8::Value> args[] = {
gin::StringToSymbol(isolate, event_name),
v8::Undefined(isolate),
extra_parameters_spec,
};
v8::TryCatch try_catch(isolate);
v8::Local<v8::Value> event;
if (!JSRunner::Get(context)
->RunJSFunctionSync(get_event, context, args)
.ToLocal(&event)) {
LOG(ERROR) << "Unexpected error when creating custom webRequest event: "
<< "`createWebRequestEvent` function did not successfully run.";
event = v8::Undefined(isolate);
}
*event_out = event;
return true;
}
}