fix: use BlockedRequest
struct to handle webRequest
data (#42647)
Fixes an issue where Chromium could crash on a dangling unretained pointer in one of several webRequest functions. This was happening as a result of the fact that we had outstanding blocking requests continue to reference state owned by ProxyingWebsocket and ProxyingURLLoaderFactory after the requests were destroyed. This had been going on for a few years, and was likely leading to some ongoing memory issues. To fix this, we need to ensure that all state is cleaned up in OnRequestWillBeDestroyed. I chose to create a new BlockedRequest struct to do so, which approximates the approach that upstream takes. The complexities of doing so also made our templated approach more trouble than it felt worth, so i pried that apart into separate handlers.
This commit is contained in:
parent
8a8241163d
commit
1729a9868c
3 changed files with 304 additions and 111 deletions
|
@ -84,6 +84,10 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
|||
WebRequest(v8::Isolate* isolate, content::BrowserContext* browser_context);
|
||||
~WebRequest() override;
|
||||
|
||||
// Contains info about requests that are blocked waiting for a response from
|
||||
// the user.
|
||||
struct BlockedRequest;
|
||||
|
||||
enum class SimpleEvent {
|
||||
kOnSendHeaders,
|
||||
kOnBeforeRedirect,
|
||||
|
@ -91,6 +95,7 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
|||
kOnCompleted,
|
||||
kOnErrorOccurred,
|
||||
};
|
||||
|
||||
enum class ResponseEvent {
|
||||
kOnBeforeRequest,
|
||||
kOnBeforeSendHeaders,
|
||||
|
@ -113,15 +118,30 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
|||
void HandleSimpleEvent(SimpleEvent event,
|
||||
extensions::WebRequestInfo* info,
|
||||
Args... args);
|
||||
template <typename Out, typename... Args>
|
||||
int HandleResponseEvent(ResponseEvent event,
|
||||
extensions::WebRequestInfo* info,
|
||||
net::CompletionOnceCallback callback,
|
||||
Out out,
|
||||
Args... args);
|
||||
|
||||
template <typename T>
|
||||
void OnListenerResult(uint64_t id, T out, v8::Local<v8::Value> response);
|
||||
int HandleOnBeforeRequestResponseEvent(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
GURL* redirect_url);
|
||||
int HandleOnBeforeSendHeadersResponseEvent(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
BeforeSendHeadersCallback callback,
|
||||
net::HttpRequestHeaders* headers);
|
||||
int HandleOnHeadersReceivedResponseEvent(
|
||||
extensions::WebRequestInfo* info,
|
||||
const network::ResourceRequest& request,
|
||||
net::CompletionOnceCallback callback,
|
||||
const net::HttpResponseHeaders* original_response_headers,
|
||||
scoped_refptr<net::HttpResponseHeaders>* override_response_headers);
|
||||
|
||||
void OnBeforeRequestListenerResult(uint64_t id,
|
||||
v8::Local<v8::Value> response);
|
||||
void OnBeforeSendHeadersListenerResult(uint64_t id,
|
||||
v8::Local<v8::Value> response);
|
||||
void OnHeadersReceivedListenerResult(uint64_t id,
|
||||
v8::Local<v8::Value> response);
|
||||
|
||||
class RequestFilter {
|
||||
public:
|
||||
|
@ -164,7 +184,7 @@ class WebRequest : public gin::Wrappable<WebRequest>, public WebRequestAPI {
|
|||
|
||||
std::map<SimpleEvent, SimpleListenerInfo> simple_listeners_;
|
||||
std::map<ResponseEvent, ResponseListenerInfo> response_listeners_;
|
||||
std::map<uint64_t, net::CompletionOnceCallback> callbacks_;
|
||||
std::map<uint64_t, BlockedRequest> blocked_requests_;
|
||||
|
||||
// Weak-ref, it manages us.
|
||||
raw_ptr<content::BrowserContext> browser_context_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue