mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-17 06:48:37 +02:00
Add proxy example (#225)
* Add proxy example * Updated after review comments
This commit is contained in:
22
proxy-blocker/README.md
Normal file
22
proxy-blocker/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# proxy-filter
|
||||
|
||||
## What it does
|
||||
|
||||
This add-on registers a [PAC script](https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_%28PAC%29_file) using the proxy API.
|
||||
|
||||
The PAC script is initialized with a list of hostnames: it blocks requests to any hosts that are in the list.
|
||||
|
||||
The list is given the following default values: `["example.com", "example.org"]`, but the user can add and remove hosts using the add-on's options page.
|
||||
|
||||
Note that the hostname-matching is very simple: hostnames must exactly match an entry in the list if they are to be blocked. So with the default settings, "example.org" would be blocked but "www.example.org" would be permitted.
|
||||
|
||||
To try it out:
|
||||
* install it
|
||||
* try visiting `http://example.com`, and see it is blocked
|
||||
* visit `about:addons`, open the add-on's preferences, and try changing the hostnames in the text box
|
||||
* try visiting some different pages, to see the effect of your changes.
|
||||
|
||||
## What it shows
|
||||
|
||||
* How to implement a simple PAC script, and register it using the proxy API.
|
||||
* How to exchange messages between a PAC script and a background script.
|
||||
55
proxy-blocker/background/proxy-handler.js
Normal file
55
proxy-blocker/background/proxy-handler.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// Location of the proxy script, relative to manifest.json
|
||||
const proxyScriptURL = "proxy/proxy-script.js";
|
||||
|
||||
// Default settings. If there is nothing in storage, use these values.
|
||||
const defaultSettings = {
|
||||
blockedHosts: ["example.com", "example.org"]
|
||||
}
|
||||
|
||||
// Register the proxy script
|
||||
browser.proxy.registerProxyScript(proxyScriptURL);
|
||||
|
||||
// Log any errors from the proxy script
|
||||
browser.proxy.onProxyError.addListener(error => {
|
||||
console.error(`Proxy error: ${error.message}`);
|
||||
});
|
||||
|
||||
// Initialize the proxy
|
||||
function handleInit(message) {
|
||||
// update the proxy whenever stored settings change
|
||||
browser.storage.onChanged.addListener((newSettings) => {
|
||||
browser.runtime.sendMessage(newSettings.blockedHosts.newValue, {toProxyScript: true});
|
||||
});
|
||||
|
||||
// get the current settings, then...
|
||||
browser.storage.local.get()
|
||||
.then((storedSettings) => {
|
||||
// if there are stored settings, update the proxy with them...
|
||||
if (storedSettings.blockedHosts) {
|
||||
browser.runtime.sendMessage(storedSettings.blockedHosts, {toProxyScript: true});
|
||||
// ...otherwise, initialize storage with the default values
|
||||
} else {
|
||||
browser.storage.local.set(defaultSettings);
|
||||
}
|
||||
|
||||
})
|
||||
.catch(()=> {
|
||||
console.log("Error retrieving stored settings");
|
||||
});
|
||||
}
|
||||
|
||||
function handleMessage(message, sender) {
|
||||
// only handle messages from the proxy script
|
||||
if (sender.url != browser.extension.getURL(proxyScriptURL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message === "init") {
|
||||
handleInit(message);
|
||||
} else {
|
||||
// after the init message the only other messages are status messages
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
|
||||
browser.runtime.onMessage.addListener(handleMessage);
|
||||
1
proxy-blocker/icons/LICENSE
Normal file
1
proxy-blocker/icons/LICENSE
Normal file
@@ -0,0 +1 @@
|
||||
The "lock".svg" icon is taken from the Material Core iconset and is used under the terms of its license: https://www.iconfinder.com/iconsets/material-core.
|
||||
1
proxy-blocker/icons/block.svg
Normal file
1
proxy-blocker/icons/block.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><svg height="20px" version="1.1" viewBox="0 0 20 20" width="20px" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" xmlns:xlink="http://www.w3.org/1999/xlink"><title/><desc/><defs/><g fill="none" fill-rule="evenodd" id="Page-1" stroke="none" stroke-width="1"><g fill="#000000" id="Core" transform="translate(-170.000000, -44.000000)"><g id="block" transform="translate(170.000000, 44.000000)"><path d="M10,0 C4.5,0 0,4.5 0,10 C0,15.5 4.5,20 10,20 C15.5,20 20,15.5 20,10 C20,4.5 15.5,0 10,0 L10,0 Z M2,10 C2,5.6 5.6,2 10,2 C11.8,2 13.5,2.6 14.9,3.7 L3.7,14.9 C2.6,13.5 2,11.8 2,10 L2,10 Z M10,18 C8.2,18 6.5,17.4 5.1,16.3 L16.3,5.1 C17.4,6.5 18,8.2 18,10 C18,14.4 14.4,18 10,18 L10,18 Z" id="Shape"/></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 779 B |
31
proxy-blocker/manifest.json
Normal file
31
proxy-blocker/manifest.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
|
||||
"manifest_version": 2,
|
||||
"name": "Proxy-blocker",
|
||||
"description": "Uses the proxy API to block requests to specific hosts.",
|
||||
"version": "1.0",
|
||||
|
||||
"icons": {
|
||||
"48": "icons/block.svg",
|
||||
"96": "icons/block.svg"
|
||||
},
|
||||
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"strict_min_version": "55.0a1"
|
||||
}
|
||||
},
|
||||
|
||||
"background": {
|
||||
"scripts": [
|
||||
"background/proxy-handler.js"
|
||||
]
|
||||
},
|
||||
|
||||
"options_ui": {
|
||||
"page": "options/options.html"
|
||||
},
|
||||
|
||||
"permissions": ["proxy", "storage"]
|
||||
|
||||
}
|
||||
14
proxy-blocker/options/options.css
Normal file
14
proxy-blocker/options/options.css
Normal file
@@ -0,0 +1,14 @@
|
||||
body {
|
||||
width: 25em;
|
||||
font-family: "Open Sans Light", sans-serif;
|
||||
font-size: 0.9em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.title, #blocked-hosts {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
19
proxy-blocker/options/options.html
Normal file
19
proxy-blocker/options/options.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="options.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<section>
|
||||
<span class="title">Hosts to block:</span>
|
||||
<textarea id="blocked-hosts" rows="10" cols="50"></textarea>
|
||||
</section>
|
||||
|
||||
<script src="options.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
25
proxy-blocker/options/options.js
Normal file
25
proxy-blocker/options/options.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const blockedHostsTextArea = document.querySelector("#blocked-hosts");
|
||||
|
||||
// Store the currently selected settings using browser.storage.local.
|
||||
function storeSettings() {
|
||||
let blockedHosts = blockedHostsTextArea.value.split("\n");
|
||||
browser.storage.local.set({
|
||||
blockedHosts
|
||||
});
|
||||
}
|
||||
|
||||
// Update the options UI with the settings values retrieved from storage,
|
||||
// or the default settings if the stored settings are empty.
|
||||
function updateUI(restoredSettings) {
|
||||
blockedHostsTextArea.value = restoredSettings.blockedHosts.join("\n");
|
||||
}
|
||||
|
||||
function onError(e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// On opening the options page, fetch stored settings and update the UI with them.
|
||||
browser.storage.local.get().then(updateUI, onError);
|
||||
|
||||
// Whenever the contents of the textarea changes, save the new values
|
||||
blockedHostsTextArea.addEventListener("change", storeSettings);
|
||||
21
proxy-blocker/proxy/proxy-script.js
Normal file
21
proxy-blocker/proxy/proxy-script.js
Normal file
@@ -0,0 +1,21 @@
|
||||
var blockedHosts = [];
|
||||
const allow = "DIRECT 1234";
|
||||
const deny = "PROXY 127.0.0.1:65535";
|
||||
|
||||
// tell the background script that we are ready
|
||||
browser.runtime.sendMessage("init");
|
||||
|
||||
// listen for updates to the blocked host list
|
||||
browser.runtime.onMessage.addListener((message) => {
|
||||
blockedHosts = message;
|
||||
});
|
||||
|
||||
// required PAC function that will be called to determine
|
||||
// if a proxy should be used.
|
||||
function FindProxyForURL(url, host) {
|
||||
if (blockedHosts.indexOf(host) != -1) {
|
||||
browser.runtime.sendMessage(`Proxy-blocker: blocked ${url}`);
|
||||
return deny;
|
||||
}
|
||||
return allow;
|
||||
}
|
||||
Reference in New Issue
Block a user