From ea6b948f3b813a123bc72ebc39658270a0fcef89 Mon Sep 17 00:00:00 2001 From: ownedbywuigi Date: Tue, 31 Mar 2026 23:52:46 +0100 Subject: [PATCH] (from mypal68) Full webRequest support --- .vscode/settings.json | 6 +- dom/bindings/Bindings.conf | 14 + dom/webidl/ChannelWrapper.webidl | 491 +++++++ dom/webidl/StreamFilter.webidl | 143 ++ dom/webidl/StreamFilterDataEvent.webidl | 28 + dom/webidl/moz.build | 3 + .../webextensions/ext-webRequest.js | 46 +- toolkit/components/webextensions/moz.build | 5 +- .../webextensions/schemas/web_request.json | 47 +- .../webrequest/ChannelWrapper.cpp | 997 ++++++++++++++ .../webextensions/webrequest/ChannelWrapper.h | 330 +++++ .../webrequest/PStreamFilter.ipdl | 38 + .../webextensions/webrequest/SecurityInfo.jsm | 328 +++++ .../webextensions/webrequest/StreamFilter.cpp | 261 ++++ .../webextensions/webrequest/StreamFilter.h | 94 ++ .../webrequest/StreamFilterBase.h | 36 + .../webrequest/StreamFilterChild.cpp | 515 ++++++++ .../webrequest/StreamFilterChild.h | 133 ++ .../webrequest/StreamFilterEvents.cpp | 51 + .../webrequest/StreamFilterEvents.h | 65 + .../webrequest/StreamFilterParent.cpp | 751 +++++++++++ .../webrequest/StreamFilterParent.h | 180 +++ .../webextensions/webrequest/WebRequest.jsm | 1150 +++++++++++++++++ .../webrequest/WebRequestService.cpp | 53 + .../webrequest/WebRequestService.h | 73 ++ .../webrequest/WebRequestUpload.jsm | 552 ++++++++ .../webextensions/webrequest/moz.build | 52 + toolkit/modules/moz.build | 2 - 28 files changed, 6431 insertions(+), 13 deletions(-) create mode 100644 dom/webidl/ChannelWrapper.webidl create mode 100644 dom/webidl/StreamFilter.webidl create mode 100644 dom/webidl/StreamFilterDataEvent.webidl create mode 100644 toolkit/components/webextensions/webrequest/ChannelWrapper.cpp create mode 100644 toolkit/components/webextensions/webrequest/ChannelWrapper.h create mode 100644 toolkit/components/webextensions/webrequest/PStreamFilter.ipdl create mode 100644 toolkit/components/webextensions/webrequest/SecurityInfo.jsm create mode 100644 toolkit/components/webextensions/webrequest/StreamFilter.cpp create mode 100644 toolkit/components/webextensions/webrequest/StreamFilter.h create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterBase.h create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterChild.cpp create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterChild.h create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterEvents.cpp create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterEvents.h create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterParent.cpp create mode 100644 toolkit/components/webextensions/webrequest/StreamFilterParent.h create mode 100644 toolkit/components/webextensions/webrequest/WebRequest.jsm create mode 100644 toolkit/components/webextensions/webrequest/WebRequestService.cpp create mode 100644 toolkit/components/webextensions/webrequest/WebRequestService.h create mode 100644 toolkit/components/webextensions/webrequest/WebRequestUpload.jsm create mode 100644 toolkit/components/webextensions/webrequest/moz.build diff --git a/.vscode/settings.json b/.vscode/settings.json index ca6fe06853..2e6df67cf3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,7 @@ { - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, + "chat.tools.terminal.autoApprove": { + "ForEach-Object": true, + "Get-Item": true + } } \ No newline at end of file diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 5312cc0261..ffea1f2944 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -867,6 +867,20 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/WorkerScope.h', }, +'ChannelWrapper': { + 'nativeType': 'mozilla::extensions::ChannelWrapper', + 'headerFile': 'mozilla/extensions/ChannelWrapper.h', +}, + +'StreamFilter': { + 'nativeType': 'mozilla::extensions::StreamFilter', +}, + +'StreamFilterDataEvent': { + 'nativeType': 'mozilla::extensions::StreamFilterDataEvent', + 'headerFile': 'mozilla/extensions/StreamFilterEvents.h', +}, + 'Storage': { 'nativeType': 'mozilla::dom::DOMStorage', }, diff --git a/dom/webidl/ChannelWrapper.webidl b/dom/webidl/ChannelWrapper.webidl new file mode 100644 index 0000000000..8a64dcde23 --- /dev/null +++ b/dom/webidl/ChannelWrapper.webidl @@ -0,0 +1,491 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +interface MozChannel; +interface URI; +interface nsISupports; + +/** + * Load types that correspond to the external types in nsIContentPolicy.idl. + * Please also update that IDL when updating this list. + */ +enum MozContentPolicyType { + "main_frame", + "sub_frame", + "stylesheet", + "script", + "image", + "object", + "object_subrequest", + "xmlhttprequest", + "fetch", + "xslt", + "ping", + "beacon", + "xml_dtd", + "font", + "media", + "websocket", + "csp_report", + "imageset", + "web_manifest", + "speculative", + "other" +}; + +/** + * A thin wrapper around nsIChannel and nsIHttpChannel that allows JS + * callers to access them without XPConnect overhead. + */ +[ChromeOnly, Exposed=Window] +interface ChannelWrapper : EventTarget { + /** + * Returns the wrapper instance for the given channel. The same wrapper is + * always returned for a given channel. + */ + static ChannelWrapper get(MozChannel channel); + + /** + * Returns the wrapper instance for the given channel. The same wrapper is + * always returned for a given channel. + */ + static ChannelWrapper? getRegisteredChannel(unsigned long long aChannelId, + DOMString extensionId, + nsISupports? remoteTab); + + /** + * A unique ID for for the requests which remains constant throughout the + * redirect chain. + */ + [Constant, StoreInSlot] + readonly attribute unsigned long long id; + + // Not technically pure, since it's backed by a weak reference, but if JS + // has a reference to the previous value, we can depend on it not being + // collected. + [Pure] + attribute MozChannel? channel; + + + /** + * Cancels the request with the given nsresult status code. + * + * The optional reason parameter should be one of the BLOCKING_REASON + * constants from nsILoadInfo.idl + */ + [Throws] + void cancel(unsigned long result, optional unsigned long reason = 0); + + /** + * Redirects the wrapped HTTP channel to the given URI. For other channel + * types, this method will throw. The redirect is an internal redirect, and + * the behavior is the same as nsIHttpChannel.redirectTo. + */ + [Throws] + void redirectTo(URI url); + + /** + * Requests an upgrade of the HTTP channel to a secure request. For other channel + * types, this method will throw. The redirect is an internal redirect, and + * the behavior is the same as nsIHttpChannel.upgradeToSecure. Setting this + * flag is only effective during the WebRequest.onBeforeRequest in + * Web Extensions, calling this at any other point during the request will + * have no effect. Setting this flag in addition to calling redirectTo + * results in the redirect happening rather than the upgrade request. + */ + [Throws] + void upgradeToSecure(); + + /** + * The content type of the request, usually as read from the Content-Type + * header. This should be used in preference to the header to determine the + * content type of the channel. + */ + [Pure] + attribute ByteString contentType; + + + /** + * For HTTP requests, the request method (e.g., GET, POST, HEAD). For other + * request types, returns an empty string. + */ + [Cached, Pure] + readonly attribute ByteString method; + + /** + * For requests with LoadInfo, the content policy type that corresponds to + * the request. For requests without LoadInfo, returns "other". + */ + [Cached, Pure] + readonly attribute MozContentPolicyType type; + + + /** + * When true, the request is currently suspended by the wrapper. When false, + * the request is not suspended by the wrapper, but may still be suspended + * by another caller. + */ + [Pure, SetterThrows] + attribute boolean suspended; + + + /** + * The final URI of the channel (as returned by NS_GetFinalChannelURI) after + * any redirects have been processed. + */ + [Cached, Pure] + readonly attribute URI finalURI; + + /** + * The string version of finalURI (but cheaper to access than + * finalURI.spec). + */ + [Cached, Pure] + readonly attribute DOMString finalURL; + + + /** + * Returns true if the request matches the given request filter, and the + * given extension has permission to access it. + */ + boolean matches(optional MozRequestFilter filter, + DOMString extensionId, + optional MozRequestMatchOptions options); + + + /** + * Register's this channel as traceable by the given add-on when accessed + * via the process of the given remote browser. + */ + void registerTraceableChannel(DOMString extensionId, nsISupports? remoteTab); + + /** + * The current HTTP status code of the request. This will be 0 if a response + * has not yet been received, or if the request is not an HTTP request. + */ + [Cached, Pure] + readonly attribute unsigned long statusCode; + + /** + * The HTTP status line for the request (e.g., "HTTP/1.0 200 Success"). This + * will be an empty string if a response has not yet been received, or if + * the request is not an HTTP request. + */ + [Cached, Pure] + readonly attribute ByteString statusLine; + + + /** + * If the request has failed or been canceled, an opaque string representing + * the error. For requests that failed at the NSS layer, this is an NSS + * error message. For requests that failed for any other reason, it is the + * name of an nsresult error code. For requests which haven't failed, this + * is null. + * + * This string is used in the error message when notifying extension + * webRequest listeners of failure. The documentation specifically states + * that this value MUST NOT be parsed, and is only meant to be displayed to + * humans, but we all know how that works in real life. + */ + [Cached, Pure] + readonly attribute DOMString? errorString; + + /** + * Dispatched when the channel is closed with an error status. Check + * errorString for the error details. + */ + attribute EventHandler onerror; + + /** + * Checks the request's current status and dispatches an error event if the + * request has failed and one has not already been dispatched. + */ + void errorCheck(); + + + /** + * Dispatched when the channel begins receiving data. + */ + attribute EventHandler onstart; + + /** + * Dispatched when the channel has finished receiving data. + */ + attribute EventHandler onstop; + + + /** + * Information about the proxy server which is handling this request, or + * null if the request is not proxied. + */ + [Cached, Frozen, GetterThrows, Pure] + readonly attribute MozProxyInfo? proxyInfo; + + /** + * For HTTP requests, the IP address of the remote server handling the + * request. For other request types, returns null. + */ + [Cached, Pure] + readonly attribute ByteString? remoteAddress; + + + /** + * True if this load was triggered by a system caller. This currently always + * false if the request has no LoadInfo or is a top-level document load. + */ + [Cached, Pure] + readonly attribute boolean isSystemLoad; + + /** + * The URL of the principal that triggered this load. This is equivalent to + * the LoadInfo's triggeringPrincipal, and will only ever be null for + * requests without LoadInfo. + */ + [Cached, Pure] + readonly attribute ByteString? originURL; + + /** + * The URL of the document loading the content for this request. This is + * equivalent to the LoadInfo's loadingPrincipal. This may only ever be null + * for top-level requests and requests without LoadInfo. + */ + [Cached, Pure] + readonly attribute ByteString? documentURL; + + /** + * The URI version of originURL. Will be null only when originURL is null. + */ + [Pure] + readonly attribute URI? originURI; + + /** + * The URI version of documentURL. Will be null only when documentURL is + * null. + */ + [Pure] + readonly attribute URI? documentURI; + + + /** + * True if extensions may modify this request. This is currently false only + * if the request belongs to a document which has access to the + * mozAddonManager API. + */ + [Cached, GetterThrows, Pure] + readonly attribute boolean canModify; + + + /** + * The outer window ID of the frame that the request belongs to, or 0 if it + * is a top-level load or does not belong to a document. + */ + [Cached, Constant] + readonly attribute long long windowId; + + /** + * The outer window ID of the parent frame of the window that the request + * belongs to, 0 if that parent frame is the top-level frame, and -1 if the + * request belongs to a top-level frame. + */ + [Cached, Constant] + readonly attribute long long parentWindowId; + + /** + * For cross-process requests, the or