Bug 1604618 support request cancel reason in webrequest r=rpl,Honza

Support cancel reason so devtools, download panel, etc. can understand that an extension cancelled a request.

Differential Revision: https://phabricator.services.mozilla.com/D57537

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Shane Caraveo 2020-01-13 20:30:26 +00:00
Родитель 3d28702804
Коммит 4d3b7a6d20
7 изменённых файлов: 94 добавлений и 4 удалений

Просмотреть файл

@ -95,9 +95,12 @@ interface ChannelWrapper : EventTarget {
/**
* 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);
void cancel(unsigned long result, optional unsigned long reason = 0);
/**
* Redirects the wrapped HTTP channel to the given URI. For other channel

Просмотреть файл

@ -1188,6 +1188,8 @@ interface nsILoadInfo : nsISupports
const uint32_t BLOCKING_REASON_CONTENT_POLICY_PRELOAD = 4006;
// The reason used when SEC_REQUIRE_SAME_ORIGIN_* is set and not satisifed.
const uint32_t BLOCKING_REASON_NOT_SAME_ORIGIN = 5000;
// The reason used when an extension cancels the request via the WebRequest api.
const uint32_t BLOCKING_REASON_EXTENSION_WEBREQUEST = 6000;
/**
* If the request associated with this load info was blocked by some of

Просмотреть файл

@ -0,0 +1,69 @@
"use strict";
const server = createHttpServer();
const gServerUrl = `http://localhost:${server.identity.primaryPort}`;
server.registerPathHandler("/dummy", (request, response) => {
response.setStatusLine(request.httpVersion, 200, "OK");
response.write("ok");
});
add_task(async function test_cancel_with_reason() {
let ext = ExtensionTestUtils.loadExtension({
manifest: {
applications: { gecko: { id: "cancel@test" } },
permissions: ["webRequest", "webRequestBlocking", "<all_urls>"],
},
background() {
browser.webRequest.onBeforeRequest.addListener(
() => {
return { cancel: true };
},
{ urls: ["*://*/*"] },
["blocking"]
);
},
});
await ext.startup();
let data = await new Promise(resolve => {
let ssm = Services.scriptSecurityManager;
let channel = NetUtil.newChannel({
uri: `${gServerUrl}/dummy`,
loadingPrincipal: ssm.createContentPrincipalFromOrigin(
"http://localhost"
),
contentPolicyType: Ci.nsIContentPolicy.TYPE_XMLHTTPREQUEST,
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
});
channel.asyncOpen({
QueryInterface: ChromeUtils.generateQI([Ci.nsIStreamListener]),
onStartRequest(request) {},
onStopRequest(request, statusCode) {
let properties = request.QueryInterface(Ci.nsIPropertyBag);
let id = properties.getProperty("cancelledByExtension");
let reason = request.loadInfo.requestBlockingReason;
resolve({ reason, id });
},
onDataAvailable() {},
});
});
Assert.equal(
Ci.nsILoadInfo.BLOCKING_REASON_EXTENSION_WEBREQUEST,
data.reason,
"extension cancelled request"
);
Assert.equal(
ext.id,
data.id,
"extension id attached to channel property bag"
);
await ext.unload();
});

Просмотреть файл

@ -165,6 +165,7 @@ skip-if = true # Too frequent intermittent failures
skip-if = os == "android" && debug
[test_ext_webRequest_cached.js]
skip-if = os == "android" && processor != "x86_64" # Bug 1573511
[test_ext_webRequest_cancelWithReason.js]
[test_ext_webRequest_filterResponseData.js]
skip-if = os == "android" && debug
[test_ext_webRequest_incognito.js]

Просмотреть файл

@ -206,9 +206,14 @@ void ChannelWrapper::ClearCachedAttributes() {
* ...
*****************************************************************************/
void ChannelWrapper::Cancel(uint32_t aResult, ErrorResult& aRv) {
void ChannelWrapper::Cancel(uint32_t aResult, uint32_t aReason,
ErrorResult& aRv) {
nsresult rv = NS_ERROR_UNEXPECTED;
if (nsCOMPtr<nsIChannel> chan = MaybeChannel()) {
nsCOMPtr<nsILoadInfo> loadInfo = GetLoadInfo();
if (aReason > 0 && loadInfo) {
loadInfo->SetRequestBlockingReason(aReason);
}
rv = chan->Cancel(nsresult(aResult));
ErrorCheck();
}

Просмотреть файл

@ -135,7 +135,7 @@ class ChannelWrapper final : public DOMEventTargetHelper,
void SetChannel(nsIChannel* aChannel);
void Cancel(uint32_t result, ErrorResult& aRv);
void Cancel(uint32_t result, uint32_t reason, ErrorResult& aRv);
void RedirectTo(nsIURI* uri, ErrorResult& aRv);
void UpgradeToSecure(ErrorResult& aRv);

Просмотреть файл

@ -972,7 +972,17 @@ HttpObserverManager = {
if (result.cancel) {
channel.suspended = false;
channel.cancel(Cr.NS_ERROR_ABORT);
channel.cancel(
Cr.NS_ERROR_ABORT,
Ci.nsILoadInfo.BLOCKING_REASON_EXTENSION_WEBREQUEST
);
let { policy } = opts;
if (policy) {
let properties = channel.channel.QueryInterface(
Ci.nsIWritablePropertyBag
);
properties.setProperty("cancelledByExtension", policy.id);
}
return;
}