feat: migrate webRequest module to NetworkService (Part 5) (#19714)
* Pass WebRequest to ProxyingURLLoaderFactory * Call WebRequestAPI in InProgressRequest * Store the listeners * Pass the request and response * Add stub to handle the events * Use extensions::WebRequestInfo * Make sure webRequest is managed by Session * chore: make creation of WebRequestNS more clear * fix: check WebContents for service workers
This commit is contained in:
parent
9713fa09e7
commit
69eac0d9d2
7 changed files with 365 additions and 46 deletions
|
@ -4,13 +4,14 @@
|
|||
|
||||
#include "shell/browser/api/atom_api_web_request_ns.h"
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "extensions/common/url_pattern.h"
|
||||
#include "gin/converter.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "shell/browser/api/atom_api_session.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/common/gin_converters/callback_converter_gin_adapter.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
|
@ -37,12 +38,56 @@ namespace electron {
|
|||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* kUserDataKey = "WebRequestNS";
|
||||
|
||||
// BrowserContext <=> WebRequestNS relationship.
|
||||
struct UserData : public base::SupportsUserData::Data {
|
||||
explicit UserData(WebRequestNS* data) : data(data) {}
|
||||
WebRequestNS* data;
|
||||
};
|
||||
|
||||
// Test whether the URL of |request| matches |patterns|.
|
||||
bool MatchesFilterCondition(extensions::WebRequestInfo* request,
|
||||
const std::set<URLPattern>& patterns) {
|
||||
if (patterns.empty())
|
||||
return true;
|
||||
|
||||
for (const auto& pattern : patterns) {
|
||||
if (pattern.MatchesURL(request->url))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
gin::WrapperInfo WebRequestNS::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
WebRequestNS::WebRequestNS(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {}
|
||||
WebRequestNS::SimpleListenerInfo::SimpleListenerInfo(
|
||||
std::set<URLPattern> patterns_,
|
||||
SimpleListener listener_)
|
||||
: url_patterns(std::move(patterns_)), listener(listener_) {}
|
||||
WebRequestNS::SimpleListenerInfo::SimpleListenerInfo() = default;
|
||||
WebRequestNS::SimpleListenerInfo::~SimpleListenerInfo() = default;
|
||||
|
||||
WebRequestNS::~WebRequestNS() = default;
|
||||
WebRequestNS::ResponseListenerInfo::ResponseListenerInfo(
|
||||
std::set<URLPattern> patterns_,
|
||||
ResponseListener listener_)
|
||||
: url_patterns(std::move(patterns_)), listener(listener_) {}
|
||||
WebRequestNS::ResponseListenerInfo::ResponseListenerInfo() = default;
|
||||
WebRequestNS::ResponseListenerInfo::~ResponseListenerInfo() = default;
|
||||
|
||||
WebRequestNS::WebRequestNS(v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
browser_context_->SetUserData(kUserDataKey, std::make_unique<UserData>(this));
|
||||
}
|
||||
|
||||
WebRequestNS::~WebRequestNS() {
|
||||
browser_context_->RemoveUserData(kUserDataKey);
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder WebRequestNS::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
|
@ -68,18 +113,70 @@ const char* WebRequestNS::GetTypeName() {
|
|||
return "WebRequest";
|
||||
}
|
||||
|
||||
int WebRequestNS::OnBeforeRequest(extensions::WebRequestInfo* request,
|
||||
net::CompletionOnceCallback callback,
|
||||
GURL* new_url) {
|
||||
return HandleResponseEvent(kOnBeforeRequest, request, std::move(callback),
|
||||
new_url);
|
||||
}
|
||||
|
||||
int WebRequestNS::OnBeforeSendHeaders(extensions::WebRequestInfo* request,
|
||||
BeforeSendHeadersCallback callback,
|
||||
net::HttpRequestHeaders* headers) {
|
||||
// TODO(zcbenz): Figure out how to handle this generally.
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
int WebRequestNS::OnHeadersReceived(
|
||||
extensions::WebRequestInfo* request,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
|
||||
GURL* allowed_unsafe_redirect_url) {
|
||||
return HandleResponseEvent(kOnHeadersReceived, request, std::move(callback),
|
||||
original_response_headers,
|
||||
override_response_headers,
|
||||
allowed_unsafe_redirect_url);
|
||||
}
|
||||
|
||||
void WebRequestNS::OnSendHeaders(extensions::WebRequestInfo* request,
|
||||
const net::HttpRequestHeaders& headers) {
|
||||
HandleSimpleEvent(kOnSendHeaders, request, headers);
|
||||
}
|
||||
|
||||
void WebRequestNS::OnBeforeRedirect(extensions::WebRequestInfo* request,
|
||||
const GURL& new_location) {
|
||||
HandleSimpleEvent(kOnBeforeRedirect, request, new_location);
|
||||
}
|
||||
|
||||
void WebRequestNS::OnResponseStarted(extensions::WebRequestInfo* request) {
|
||||
HandleSimpleEvent(kOnResponseStarted, request);
|
||||
}
|
||||
|
||||
void WebRequestNS::OnErrorOccurred(extensions::WebRequestInfo* request,
|
||||
int net_error) {
|
||||
HandleSimpleEvent(kOnErrorOccurred, request, net_error);
|
||||
}
|
||||
|
||||
void WebRequestNS::OnCompleted(extensions::WebRequestInfo* request,
|
||||
int net_error) {
|
||||
HandleSimpleEvent(kOnCompleted, request, net_error);
|
||||
}
|
||||
|
||||
template <WebRequestNS::SimpleEvent event>
|
||||
void WebRequestNS::SetSimpleListener(gin::Arguments* args) {
|
||||
SetListener<SimpleListener, SimpleEvent>(event, args);
|
||||
SetListener<SimpleListener>(event, &simple_listeners_, args);
|
||||
}
|
||||
|
||||
template <WebRequestNS::ResponseEvent event>
|
||||
void WebRequestNS::SetResponseListener(gin::Arguments* args) {
|
||||
SetListener<ResponseListener, ResponseEvent>(event, args);
|
||||
SetListener<ResponseListener>(event, &response_listeners_, args);
|
||||
}
|
||||
|
||||
template <typename Listener, typename Event>
|
||||
void WebRequestNS::SetListener(Event event, gin::Arguments* args) {
|
||||
template <typename Listener, typename Listeners, typename Event>
|
||||
void WebRequestNS::SetListener(Event event,
|
||||
Listeners* listeners,
|
||||
gin::Arguments* args) {
|
||||
// { urls }.
|
||||
std::set<URLPattern> patterns;
|
||||
gin::Dictionary dict(args->isolate());
|
||||
|
@ -94,17 +191,76 @@ void WebRequestNS::SetListener(Event event, gin::Arguments* args) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO(zcbenz): Actually set the listeners.
|
||||
args->ThrowTypeError("This API is not implemented yet");
|
||||
if (listener.is_null())
|
||||
listeners->erase(event);
|
||||
else
|
||||
(*listeners)[event] = {std::move(patterns), std::move(listener)};
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void WebRequestNS::HandleSimpleEvent(SimpleEvent event,
|
||||
extensions::WebRequestInfo* request,
|
||||
Args... args) {
|
||||
const auto& info = simple_listeners_[event];
|
||||
if (!MatchesFilterCondition(request, info.url_patterns))
|
||||
return;
|
||||
|
||||
// TODO(zcbenz): Invoke the listener.
|
||||
}
|
||||
|
||||
template <typename Out, typename... Args>
|
||||
int WebRequestNS::HandleResponseEvent(ResponseEvent event,
|
||||
extensions::WebRequestInfo* request,
|
||||
net::CompletionOnceCallback callback,
|
||||
Out out,
|
||||
Args... args) {
|
||||
const auto& info = response_listeners_[event];
|
||||
if (!MatchesFilterCondition(request, info.url_patterns))
|
||||
return net::OK;
|
||||
|
||||
// TODO(zcbenz): Invoke the listener.
|
||||
return net::OK;
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<WebRequestNS> WebRequestNS::FromOrCreate(
|
||||
v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context) {
|
||||
gin::Handle<WebRequestNS> handle = From(isolate, browser_context);
|
||||
if (handle.IsEmpty()) {
|
||||
// Make sure the |Session| object has the |webRequest| property created.
|
||||
v8::Local<v8::Value> web_request =
|
||||
Session::CreateFrom(isolate,
|
||||
static_cast<AtomBrowserContext*>(browser_context))
|
||||
->WebRequest(isolate);
|
||||
gin::ConvertFromV8(isolate, web_request, &handle);
|
||||
}
|
||||
DCHECK(!handle.IsEmpty());
|
||||
return handle;
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<WebRequestNS> WebRequestNS::Create(
|
||||
v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context) {
|
||||
content::BrowserContext* browser_context) {
|
||||
DCHECK(From(isolate, browser_context).IsEmpty())
|
||||
<< "WebRequestNS already created";
|
||||
return gin::CreateHandle(isolate, new WebRequestNS(isolate, browser_context));
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<WebRequestNS> WebRequestNS::From(
|
||||
v8::Isolate* isolate,
|
||||
content::BrowserContext* browser_context) {
|
||||
if (!browser_context)
|
||||
return gin::Handle<WebRequestNS>();
|
||||
auto* user_data =
|
||||
static_cast<UserData*>(browser_context->GetUserData(kUserDataKey));
|
||||
if (!user_data)
|
||||
return gin::Handle<WebRequestNS>();
|
||||
return gin::CreateHandle(isolate, user_data->data);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace electron
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue