Now you can choose PAC from anticenz or antizapret

This commit is contained in:
Ilya Ig. Petrov 2015-12-21 01:28:41 +05:00
parent 1cb31c79a5
commit 67b2dc619f
6 changed files with 320 additions and 134 deletions

View File

@ -2,53 +2,52 @@
// Shows user PageAction icon if any part of the current site is being blocked and proxied. // Shows user PageAction icon if any part of the current site is being blocked and proxied.
function getHostname(url) { function getHostname(url) {
var a = document.createElement('a'); var a = document.createElement('a');
a.href = url; a.href = url;
return a.hostname; return a.hostname;
} }
function blockInform(details) { function blockInform(details) {
if (details.tabId !== -1 && details.ip === antizapret.proxyIp) { if (details.tabId !== -1 && window.antiCensorRu.pacProvider && window.antiCensorRu.pacProvider.proxyIp && details.ip === window.antiCensorRu.pacProvider.proxyIp) {
chrome.pageAction.setIcon({ chrome.pageAction.setIcon({
path: '/icons/rkn-empty.png', path: '/icons/rkn-empty.png',
tabId: details.tabId tabId: details.tabId
}); });
chrome.pageAction.getTitle( chrome.pageAction.getTitle(
{ tabId: details.tabId }, { tabId: details.tabId },
result => { result => {
if (!/\n/.test(result)) if (!/\n/.test(result))
result = 'Разблокированы:'; result = 'Разблокированы:';
var hostname = getHostname(details.url).trim(); var hostname = getHostname(details.url).trim();
var ifListed = result.split(/\r?\n/g).some( var ifListed = result.split(/\r?\n/g).some(
line => line.trim() === hostname line => line.trim() === hostname
); );
if (!ifListed) if (!ifListed)
chrome.pageAction.setTitle({ chrome.pageAction.setTitle({
title: result +'\n'+ hostname, title: result +'\n'+ hostname,
tabId: details.tabId tabId: details.tabId
}); });
} }
); );
chrome.pageAction.show(details.tabId); chrome.pageAction.show(details.tabId);
} }
} }
chrome.webRequest.onCompleted.addListener( chrome.webRequest.onCompleted.addListener(
blockInform, blockInform,
{ urls: ['<all_urls>'] } { urls: ['<all_urls>'] }
); );
chrome.webRequest.onErrorOccurred.addListener( chrome.webRequest.onErrorOccurred.addListener(
blockInform, blockInform,
{ urls: ['<all_urls>'] } { urls: ['<all_urls>'] }
); );

View File

@ -1,9 +1,9 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Антизапрет", "name": "Ненавязчивый РосКомНадзор",
"description": "Безопасный Интернет с возможностью отказаться", "description": "Потому что хорошее ценрзурирование -- это слишком сложно.y",
"version": "0.0.0.2", "version": "0.0.0.3",
"icons": { "icons": {
"128": "/icons/rkn-empty.png" "128": "/icons/rkn-empty.png"
}, },
@ -14,10 +14,17 @@
"proxy", "proxy",
"webRequest", "webRequest",
"alarms", "alarms",
"storage",
"<all_urls>" "<all_urls>"
], ],
"background": { "background": {
"scripts": ["sync-pac-script-with-antizapret.js", "block-informer.js"] "scripts": ["sync-pac-script-with-pac-provider.js", "block-informer.js"]
}, },
"page_action": {} "page_action": {
"default_popup": "/pages/choose-pac-provider/index.html"
},
"options_ui": {
"page": "/pages/choose-pac-provider/index.html",
"chrome_style": false
}
} }

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title>Выбор провайдера PAC</title>
<style>
ul {
list-style-type: none;
padding: 0;
margin: 0;
}
li {
display: block;
white-space: nowrap;
}
.off {
display: none;
}
</style>
</head>
<body>
<ul id="list-of-providers">
<li><input type="radio" name="pacProvider" id="none" checked> <label for="none">Отключить</label></li>
</ul>
<div id='status'>Загрузка...</div>
<script src="./index.js"></script>
</body>
</html>

View File

@ -0,0 +1,46 @@
function setStatusTo(msg) {
var status = document.querySelector('#status');
if (msg) {
status.classList.remove('off');
status.innerHTML = msg;
} else
status.classList.add('off');
}
chrome.runtime.getBackgroundPage( backgroundPage => {
var antiCensorRu = backgroundPage.antiCensorRu;
var ul = document.querySelector('#list-of-providers');
var _firstChild = ul.firstChild;
for(var providerKey of Object.keys(antiCensorRu.pacProviders)) {
var li = document.createElement('li');
li.innerHTML = '<input type="radio" name="pacProvider" id="'+providerKey+'"> <label for="'+providerKey+'">'+providerKey+'</label>';
ul.insertBefore( li, _firstChild );
}
var checkChosenProvider = () => {
var id = antiCensorRu.currentPacProviderKey || 'none';
var checkedRadio = document.querySelector('#'+id);
checkedRadio.checked = true;
var event = document.createEvent('HTMLEvents');
event.initEvent('change', false, true);
checkedRadio.dispatchEvent(event);
}
checkChosenProvider();
setStatusTo('');
var radios = [].slice.apply( document.querySelectorAll('[name=pacProvider]') );
for(var radio of radios) {
radio.onchange = function(event) {
setStatusTo('');
var pacKey = event.target.id;
if (pacKey === 'none')
return antiCensorRu.clearPac( () => window && window.close() );
setStatusTo('Установка...');
antiCensorRu.installPac(pacKey, () => { setStatusTo('PAC-скрипт установлен.'); if(window) window.close(); });
}
}
});

View File

@ -1,98 +0,0 @@
'use strict';
/*
Task 1. Gets IP for host proxy.antizapret.prostovpn.org with dns-lg.com.
This IP is used in block-informer to inform user when proxy is ON.
Task 2. Downloads PAC proxy script from Antizapret and sets it in Chromium settings.
Task 3. Schedules tasks 1 & 2 for every 2 hours.
*/
var antizapret = {
pacUrl: 'http://antizapret.prostovpn.org/proxy.pac',
proxyHost: 'proxy.antizapret.prostovpn.org',
proxyIp: '195.154.110.37',
};
function httpGet(url, cb) {
var cb = cb || (() => {});
var req = new XMLHttpRequest();
var ifAsync = true;
req.open('GET', url, ifAsync);
req.onload = event => {
if (req.status === 404)
return cb(event);
return cb(null, req.responseText)
};
req.onerror = cb;
req.send();
}
function getIpForHost(host, cb) {
httpGet(
'http://www.dns-lg.com/google1/'+host+'/A',
cb
);
}
function updateAntizapretProxyIp() {
getIpForHost(
antizapret.proxyHost,
(err, res) => {
if (err)
console.log(err)
else
antizapret.proxyIp = JSON.parse(res).answer[0].rdata;
}
);
}
function setPacScriptFromAntizapret() {
httpGet(
antizapret.pacUrl,
(err, res) => {
if (err)
return;
chrome.proxy.settings.clear({}, () => {
var config = {
mode: 'pac_script',
pacScript: {
mandatory: false,
data: res
}
};
chrome.proxy.settings.set( {value: config} );
});
}
);
}
function syncWithAntizapret() {
updateAntizapretProxyIp();
setPacScriptFromAntizapret();
}
chrome.runtime.onInstalled.addListener( details => {
switch(details.reason) {
case 'install':
case 'update':
syncWithAntizapret();
var reason = 'Периодичное обновление PAC-скрипта Антизапрет';
chrome.alarms.onAlarm.addListener(
alarm => {
if (alarm.name === reason) {
syncWithAntizapret();
}
}
);
chrome.alarms.create(reason, {
periodInMinutes: 2*60
});
}
});

View File

@ -0,0 +1,205 @@
'use strict';
/*
Task 1. Gets IP for host proxy.antizapret.prostovpn.org with dns-lg.com.
This IP is used in block-informer to inform user when proxy is ON.
Task 2. Downloads PAC proxy script from Antizapret and sets it in Chromium settings.
Task 3. Schedules tasks 1 & 2 for every 2 hours.
*/
/*
In background scripts use window.antiCensorRu public variables.
Thay are synced with chrome.storage so they persist restarts.
In pages window.antiCensorRu are not accessible,
use chrome.runtime.getBackgroundPage(..),
avoid old extension.getBackgroundPage.
*/
window.antiCensorRu = {
// PUBLIC
pacProviders: {
Антизапрет: {
pacUrl: 'http://antizapret.prostovpn.org/proxy.pac',
proxyHost: 'proxy.antizapret.prostovpn.org',
proxyIp: '195.154.110.37'
},
Антиценз: {
pacUrl: 'https://config.anticenz.org/proxy.pac',
proxyHost: 'gw2.anticenz.org'
}
},
_currentPacProviderKey: 'Антиценз',
get currentPacProviderKey() { return this._currentPacProviderKey },
set currentPacProviderKey(newKey) {
if (newKey && !this.pacProviders[newKey])
throw new IllegalArgumentException('No provider for key:'+newKey);
this._currentPacProviderKey = newKey;
},
get pacProvider() { return this.pacProviders[this.currentPacProviderKey] },
ifNotInstalled: true,
// PROTECTED
pushToStorage(cb) {
// Copy only settable properties.
var onlySettable = {};
for(var key of Object.keys(this))
if (Object.getOwnPropertyDescriptor(this, key).writable && typeof(this[key]) !== 'function')
onlySettable[key] = this[key]
return chrome.storage.local.set(onlySettable, cb);
},
pullFromStorage(cb) {
chrome.storage.local.get(null, storage => {
for(var key of Object.keys(storage))
this[key] = storage[key];
if (cb)
cb(storage);
});
},
syncWithPacProvider(cb) {
setPacScriptFromProvider(
this.pacProvider,
() => {
updatePacProxyIp(
this.pacProvider,
() => {
this.ifNotInstalled = false;
this.pushToStorage(cb)
}
)}
)
},
installPac(key, cb) {
if(typeof(key) === 'function') {
cb = key;
key = undefined;
}
if(key)
this.currentPacProviderKey = key;
var cb = asyncLogGroup('Installing PAC...', cb);
var reason = 'Периодичное обновление PAC-скрипта Антизапрет';
chrome.alarms.onAlarm.addListener(
alarm => {
if (alarm.name === reason)
this.syncWithPacProvider();
}
);
chrome.alarms.create(reason, {
periodInMinutes: 2*60
});
this.syncWithPacProvider(cb);
},
clearPac(cb) {
var cb = asyncLogGroup('Cearing PAC...', cb);
chrome.alarms.clearAll( () => chrome.proxy.settings.clear(
{},
() => {
this.currentPacProviderKey = undefined;
return this.pushToStorage(cb);
})
);
}
};
window.antiCensorRu.pullFromStorage(
() =>
chrome.storage.onChanged.addListener( () => window.antiCensorRu.pullFromStorage() )
)
chrome.runtime.onInstalled.addListener( details => {
switch(details.reason) {
case 'install':
case 'update':
window.antiCensorRu.pullFromStorage(
() => {
window.antiCensorRu.ifNotInstalled = true;
window.antiCensorRu.installPac();
//chrome.runtime.openOptionsPage();
}
)
}
});
// PRIVATE
function asyncLogGroup() {
var args = [].slice.apply(arguments);
var cb = args.pop();
console.group.apply(console, args);
return function() {
console.log('Finished');
console.groupEnd();
var _cb = cb || (() => {});
return _cb.apply(this, arguments);
}
}
function httpGet(url, cb) {
var cb = cb || (() => {});
var req = new XMLHttpRequest();
var ifAsync = true;
req.open('GET', url, ifAsync);
req.onload = event => {
if (req.status === 404)
return cb(event);
console.log('GETed with success.');
return cb(null, req.responseText)
};
req.onerror = cb;
req.send();
}
function updatePacProxyIp(provider, cb) {
var cb = asyncLogGroup('Getting IP for '+ provider.proxyHost +'...', cb);
httpGet(
'http://www.dns-lg.com/google1/'+ provider.proxyHost +'/A',
(err, res) => {
if (!err)
provider.proxyIp = JSON.parse(res).answer[0].rdata;
return cb(err, res);
}
);
}
function setPacScriptFromProvider(provider, cb) {
var cb = asyncLogGroup('Getting pac script from provider...', provider.pacUrl, cb);
httpGet(
provider.pacUrl,
(err, res) => {
if (err)
return cb(err);
console.log('Clearing chrome proxy settings...');
return chrome.proxy.settings.clear({}, () => {
var config = {
mode: 'pac_script',
pacScript: {
mandatory: false,
data: res
}
};
console.log('Setting chrome proxy settings...');
chrome.proxy.settings.set( {value: config}, cb );
});
}
);
}