- This document uses
Stage > Template Nameto indicate the default template to be selected in this stage. - The bold parts in the code blocks are the sections that need to be modified.
- Due to iterative reasons, the default templates here may slightly differ from the actual templates.
This rule will add x-req-a and x-req-b to https://httpbin.org/get, modify the user-agent, and remove the accept-language request header.
- Match Request > URL Prefix
let prefix = 'https://httpbin.org/get';
return details.url.startsWith(prefix);
- BeforeSendHeaders > Modify Request Header
let customHeaders = {
"x-req-a": "v1",
"x-req-b": "v2",
"user-agent": "curl/1.2",
"accept-language": null,
};
let headers = Object.entries(customHeaders)
.filter(([k, v]) => v !== null)
.map(([k, v]) => ({ name: k, value: v }));
for (let header of details.requestHeaders) {
let name = header.name.toLowerCase();
if (name in customHeaders) continue;
headers.push(header);
}
return { requestHeaders: headers };
This rule will allow CORS for the developer.mozilla.org domain, remove CSP and x-frame-options, and add x-res-a and x-res-b response headers.
- Match Request > Domain
let hostnames = ['developer.mozilla.org'];
let urlObj = new URL(details.url);
return hostnames.includes(urlObj.hostname);
- HeadersReceived > Modify Response Header
let customHeaders = {
"access-control-allow-origin": "*",
"access-control-expose-headers":"*",
"content-security-policy": null,
"content-security-policy-report-only": null,
"x-frame-options": null,
"x-res-a":"v1",
"x-res-b":"v2",
};
let headers = Object.entries(customHeaders)
.filter(([k, v]) => v !== null)
.map(([k, v]) => ({ name: k, value: v }));
for (let header of details.responseHeaders) {
let name = header.name.toLowerCase();
if (name in customHeaders) continue;
headers.push(header);
}
return { responseHeaders: headers };
This rule will cancel requests to the google-analytics.com and www.google-analytics.com domains.
- Match Request > Domain
let hostnames = ['google-analytics.com', 'www.google-analytics.com'];
let urlObj = new URL(details.url);
return hostnames.includes(urlObj.hostname);
- BeforeRequest > Cancel
This rule will cancel requests of types beacon, ping, and csp_report.
- Match Request > Main Frame
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType
let types = ['beacon', 'ping', 'csp_report'];
if (!types.includes(details.type)) return false;
return true;
- BeforeRequest > Cancel
This rule will redirect requests from http://www.google.com/recaptcha/api.js and related requests to the www.recaptcha.net domain.
- Match Request > RegExp
let regex = /^https?:\/\/(www\.)?google\.com\/recaptcha\//i;
return regex.test(details.url);
- BeforeRequest > Redirect
let urlObj = new URL(details.url);
urlObj.hostname = 'www.recaptcha.net';
let url = urlObj.href;
return { redirectUrl: url };
This rule will redirect requests under https://example.net/ except for /test/ and /favicon.ico to https://example.net/test/.
- Match Request > URL Prefix
let prefix = 'https://example.net/';
if (details.url.startsWith(prefix + 'test/')) return false;
if (details.url == prefix + 'favicon.ico') return false;
return details.url.startsWith(prefix);
- BeforeRequest > Redirect
let urlObj = new URL(details.url);
urlObj.pathname = '/test' + urlObj.pathname;
let url = urlObj.href;
return { redirectUrl: url };
This rule will directly redirect addresses like https://www.google.com/url?sa=j&url=https%3A%2F%2Fexample.com to the target.
- Match Request > URL Prefix
let prefix = 'https://www.google.com/url?';
return details.url.startsWith(prefix);
- BeforeRequest > Redirect
let urlObj = new URL(details.url);
let url = urlObj.searchParams.get('url');
if (url) return { redirectUrl: url };
This rule will replace all occurrences of Domain with DOMAIN on the page https://www.example.net/?uppercase.
- Match Request > URL
let url = 'https://www.example.net/?uppercase';
return url === details.url;
- FilterResponse > Modify Response Body
if ('error' === event.type) return console.warn('filter_error', filter.error, details.url);
if (!this.buffer) this.buffer = [];
if ('data' === event.type) {
this.buffer.push(event.data);
// Prevent default output stream writing.
return false;
}
if ('stop' !== event.type) return;
let decoder = this.decoder || (this.decoder = new TextDecoder('utf-8'));
let encoder = this.encoder || (this.encoder = new TextEncoder());
let text = this.buffer.reduce((s, buffer) => s + decoder.decode(buffer, { stream: true }), '') + decoder.decode();
console.log(text);
text = text.replace(/Domain/g, 'DOMAIN');
return encoder.encode(text);
This rule will output the request headers of the https://www.example.net/?log to the page.
- Match Request > URL
let url = 'https://www.example.net/?log';
return url === details.url;
- SendHeaders > Save Request Header
share.requestHeaders = details.requestHeaders;
- FilterResponse > Specify Response Body
if ('error' === event.type) return console.warn('filter_error', filter.error, details.url);
if ('start' !== event.type) return false;
let text = '<plaintext>' + JSON.stringify(share.requestHeaders, null, " ");
let encoder = new TextEncoder();
filter.write(encoder.encode(text));
filter.close();
This setting will ensure that requests to www.example.net do not match any rules.
- In
Settings > Rules > Global Request Matching, select theDomaintemplate, then edit and save.
let hostnames = ['www.example.net'];
let urlObj = new URL(details.url);
return ! hostnames.includes(urlObj.hostname);
This rule will cancel POST requests to https://httpbin.org/post where the request body contains ABCD.
- Match Request > HTTP Method
let methods = ['POST'];
if (!methods.includes(details.method)) return false;
let prefix = 'https://httpbin.org/post';
if (!details.url.startsWith(prefix)) return false;
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeRequest#requestbody
if (!details.requestBody) return false;
let bodyText = '';
try {
if (details.requestBody.raw) {
let decoder = new TextDecoder('utf-8');
bodyText = details.requestBody.raw.reduce((s, r) => s + decoder.decode(r.bytes, { stream: true }), '') + decoder.decode();
} else if (details.requestBody.formData) {
bodyText = JSON.stringify(details.requestBody.formData);
}
} catch (e) {
console.warn(e, details.requestBody);
}
return bodyText.includes('ABCD');
- BeforeRequest > Cancel
This rule will match pages like https://httpbin.org/status/418 with a response status code of 418 and prepend statusLine to the response body.
-
Match Request > Delayed Set Match Status
-
HeadersReceived > Set Match Status
let isMatched = details.statusCode == 418;
this.setMatchStatus(isMatched);
this.statusLine = details.statusLine;
- FilterResponse > Specify Response Body
if ('start' !== event.type) return;
// FIX: https://bugzilla.mozilla.org/show_bug.cgi?id=1543018
if (!this.matchStatus) return;
let text = this.statusLine + "\n";
let encoder = new TextEncoder();
return encoder.encode(text);
This rule will wait 5 seconds and retry up to 3 times if the request to err.example.net fails.
- Match Request > Main Frame
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType
let types = ['main_frame'];
if (!types.includes(details.type)) return false;
let methods = ['GET'];
if (!methods.includes(details.method)) return false;
let hostnames = ['err.example.net'];
let urlObj = new URL(details.url);
return hostnames.includes(urlObj.hostname);
- Error >
console.warn(details);
let urlObj = new URL(details.url);
let retry = parseInt(urlObj.searchParams.get('retry') || 0);
if (retry >= 3) return;
urlObj.searchParams.set('retry', retry + 1);
let url = urlObj.href;
setTimeout(() => {
browser.tabs.update(details.tabId, { url: url });
}, 5 * 1000);
This rule will use cookies from the httpbin.org domain for requests to example.net, *.example.net, and *.example.org.
-
Check
cookiesinSettings > Security > Permissions. -
Choose
Global Toolstemplate inSettings > Miscellaneous > Before loading rulesand save. -
Click the
Execute Nowbutton next to the textarea inBefore loading rulesor click theReload this extensionbutton inSettings > Miscellaneous > Restart. -
Match Request > Other
function f(details, share) {
if (WR.isDomain(details.url, ['example.net', '.example.org'])) return true;
return false;
}
- BeforeSendHeaders > Modify Request Header
async function f(details, share) {
let customHeaders = {
"cookie": await WR.getCookie("httpbin.org"),
};
let headers = Object.entries(customHeaders)
.filter(([k, v]) => v !== null)
.map(([k, v]) => ({ name: k, value: v }));
for (let header of details.requestHeaders) {
let name = header.name.toLowerCase();
if (name in customHeaders) continue;
headers.push(header);
}
return { requestHeaders: headers };
}