ips not forget, proxy may have several ips

This commit is contained in:
Ilya Ig. Petrov 2016-02-13 20:53:27 +05:00
parent 54b5eba5a8
commit 508069c802
7 changed files with 183 additions and 182 deletions

View File

@ -0,0 +1,121 @@
'use strict';
// Shows user browserAction icon if any part of the current site is being blocked and proxied.
/*
In what moment the title of the previous icon is cleared?
By my observations it usually takes place near tabs.onUpdate of tab status to "loading".
So if you set a title earlier it may be cleared by browser.
It pertains not only to page refesh but to newly opened pages too.
Also on loosing title see:
https://github.com/ilyaigpetrov/repository-for-chrome-bugs/blob/master/browserAction-title-lost-after-setting/background.js
Crazy parallel Chrome.
**/
window.onTabUpdated = {};
chrome.tabs.onRemoved.addListener( tabId => delete window.onTabUpdated[tabId] );
function afterTabUpdated(tabId, cb) {
if (window.onTabUpdated[tabId])
window.onTabUpdated[tabId].push(cb);
else window.onTabUpdated[tabId] = [cb];
}
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (window.onTabUpdated[tabId]) {
window.onTabUpdated[tabId].map( f => f() );
delete window.onTabUpdated[tabId];
}
});
var previousUpdateTitleFinished = Promise.resolve();
function blockInform(requestDetails) {
if (requestDetails.tabId === -1 || !window.antiCensorRu.pacProvider || !window.antiCensorRu.pacProvider.proxyIps || !window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ])
return;
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
() => new Promise(
resolve => {
var cb = () => updateTitle( requestDetails, resolve );
return requestDetails.type === 'main_frame' ? afterTabUpdated(requestDetails.tabId, cb) : cb();
}
)
);
function updateTitle(requestDetails, cb) {
chrome.browserAction.getTitle(
{ tabId: requestDetails.tabId },
title => {
var ifTitleSetAlready = /\n/.test(title);
var proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
var a = document.createElement('a');
a.href = requestDetails.url;
var hostname = a.hostname;
var ifShouldUpdateTitle = false;
var indent = ' ';
var proxyTitle = 'Прокси:';
if (!ifTitleSetAlready) {
title = 'Разблокированы:\n'+ indent + hostname +'\n'+ proxyTitle +'\n'+ indent + proxyHost;
ifShouldUpdateTitle = true;
chrome.browserAction.setBadgeText({
tabId: requestDetails.tabId,
text: requestDetails.type === 'main_frame' ? '1' : '%1'
});
} else {
var hostsProxiesPair = title.split(proxyTitle);
if (hostsProxiesPair[1].indexOf(proxyHost) === -1) {
title = title.replace(hostsProxiesPair[1], hostsProxiesPair[1] +'\n'+ indent + proxyHost);
ifShouldUpdateTitle = true;
}
if (hostsProxiesPair[0].indexOf(hostname) === -1) {
title = title.replace(proxyTitle, indent + hostname +'\n'+ proxyTitle);
ifShouldUpdateTitle = true;
var _cb = cb;
cb = () => chrome.browserAction.getBadgeText(
{tabId: requestDetails.tabId},
result => {
chrome.browserAction.setBadgeText(
{
tabId: requestDetails.tabId,
text: ( isNaN( result.charAt(0) ) && result.charAt(0) || '' ) + (hostsProxiesPair[0].split('\n').length - 1)
}
);
return _cb();
}
);
}
}
if (ifShouldUpdateTitle)
chrome.browserAction.setTitle({
title: title,
tabId: requestDetails.tabId
});
return cb();
}
);
}
}
chrome.webRequest.onResponseStarted.addListener(
blockInform,
{ urls: ['<all_urls>'] }
);
chrome.webRequest.onErrorOccurred.addListener(
blockInform,
{ urls: ['<all_urls>'] }
);

View File

@ -3,7 +3,7 @@
"name": "Обход блокировок Рунета", "name": "Обход блокировок Рунета",
"description": "Аргументы против цензуры: https://git.io/vEkI9", "description": "Аргументы против цензуры: https://git.io/vEkI9",
"version": "0.0.0.11", "version": "0.0.0.12",
"icons": { "icons": {
"128": "/icons/ribbon128.png" "128": "/icons/ribbon128.png"
}, },

View File

@ -25,7 +25,8 @@ window.antiCensorRu = {
pacUrl: 'http://antizapret.prostovpn.org/proxy.pac', pacUrl: 'http://antizapret.prostovpn.org/proxy.pac',
proxyHosts: ['proxy.antizapret.prostovpn.org'], proxyHosts: ['proxy.antizapret.prostovpn.org'],
proxyIps: { proxyIps: {
'195.154.110.37': 'proxy.antizapret.prostovpn.org' '195.154.110.37': 'proxy.antizapret.prostovpn.org',
'195.123.209.38': 'proxy.antizapret.prostovpn.org'
} }
}, },
Антиценз: { Антиценз: {
@ -37,10 +38,11 @@ window.antiCensorRu = {
}, },
Обаа_свитчах: { Обаа_свитчах: {
pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0akpCOURNS2VCTmc', pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0akpCOURNS2VCTmc',
proxyHosts: ['gw2.anticenz.org', 'proxy.antizapret.prostovpn.org'], proxyHosts: ['proxy.antizapret.prostovpn.org', 'gw2.anticenz.org'],
proxyIps: { proxyIps: {
'5.196.220.114': 'gw2.anticenz.org', '195.154.110.37': 'proxy.antizapret.prostovpn.org',
'195.154.110.37': 'proxy.antizapret.prostovpn.org' '195.123.209.38': 'proxy.antizapret.prostovpn.org',
'5.196.220.114': 'gw2.anticenz.org'
} }
} }
}, },
@ -95,7 +97,7 @@ window.antiCensorRu = {
}, },
syncWithPacProvider(cb) { syncWithPacProvider(cb) {
var cb = cb || (() => {}); var cb = asyncLogGroup('Syncing with PAC provider...', cb);
if (!this.pacProvider) if (!this.pacProvider)
return cb({clarification: 'Сперва выберите PAC-провайдера.'}); return cb({clarification: 'Сперва выберите PAC-провайдера.'});
@ -105,8 +107,11 @@ window.antiCensorRu = {
(err, res) => { (err, res) => {
if (err) if (err)
return reject(err); return reject(err);
this.lastPacUpdateStamp = Date.now(); this.lastPacUpdateStamp = Date.now();
this.ifFirstInstall = false; this.ifFirstInstall = false;
this.setAlarms();
return resolve(res); return resolve(res);
} }
) )
@ -127,15 +132,29 @@ window.antiCensorRu = {
); );
}, },
_pacUpdatePeriodInMinutes: 4*60,
setAlarms() { setAlarms() {
var nextUpdateMoment = this.lastPacUpdateStamp + this._pacUpdatePeriodInMinutes*60*1000;
var now = Date.now();
if (nextUpdateMoment < now)
nextUpdateMoment = now;
console.log( 'Next PAC update is scheduled on', new Date(nextUpdateMoment).toLocaleString('ru-RU') );
chrome.alarms.create( chrome.alarms.create(
this._periodicUpdateAlarmReason, this._periodicUpdateAlarmReason,
{ periodInMinutes: 4*60 } {
when: nextUpdateMoment,
periodInMinutes: this._pacUpdatePeriodInMinutes
}
); );
return nextUpdateMoment === now; // ifAlarmTriggered. Return value may be changed.
}, },
installPac(key, cb) { installPac(key, cb) {
if(typeof(key) === 'function') { if(typeof(key) === 'function') {
cb = key; cb = key;
key = undefined; key = undefined;
@ -144,12 +163,7 @@ window.antiCensorRu = {
if(key) if(key)
this.currentPacProviderKey = key; this.currentPacProviderKey = key;
var cb = asyncLogGroup('Installing PAC...', cb);
this.setAlarms();
return this.syncWithPacProvider(cb); return this.syncWithPacProvider(cb);
}, },
clearPac(cb) { clearPac(cb) {
@ -171,41 +185,32 @@ window.antiCensorRu = {
chrome.storage.local.get(null, oldStorage => { chrome.storage.local.get(null, oldStorage => {
console.log('Init on storage:', oldStorage); console.log('Init on storage:', oldStorage);
antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0; antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0;
// Finish each init with this callback setting alarm listeners. if (!antiCensorRu.ifFirstInstall) {
function cb(err) { // LAUNCH, RELOAD, UPDATE
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
}
chrome.alarms.onAlarm.addListener( chrome.alarms.onAlarm.addListener(
alarm => { alarm => {
if (alarm.name === antiCensorRu._periodicUpdateAlarmReason) { if (alarm.name === antiCensorRu._periodicUpdateAlarmReason) {
console.log('Periodic update triggered:', new Date()); console.log('Periodic PAC update triggered:', new Date().toLocaleString('ru-RU'));
antiCensorRu.syncWithPacProvider(); antiCensorRu.syncWithPacProvider();
} }
} }
); );
console.log('Alarm listener installed. We won\'t miss any PAC update.'); console.log('Alarm listener installed. We won\'t miss any PAC update.');
chrome.alarms.get( if (antiCensorRu.ifFirstInstall) {
antiCensorRu._periodicUpdateAlarmReason, // INSTALL
alarm => { console.log('Installing...');
if (alarm) return chrome.runtime.openOptionsPage();
console.log(
'Next update is scheduled on', new Date(alarm.scheduledTime).toLocaleString('ru-RU')
);
else if (!antiCensorRu.ifFirstInstall && antiCensorRu.pacProvider) {
antiCensorRu.setAlarms();
console.error('KNOWN BUG: Alarms were lost. See issues on GitHub. Don\'t worry, next update was rescheduled.');
}
}
);
} }
// INSTALL if (!antiCensorRu.pacProvider)
if (antiCensorRu.ifFirstInstall) { return console.log('No PAC provider set. Do nothing.');
console.log('Installing...');
return chrome.runtime.openOptionsPage(cb);
}
/* /*
1. There is no way to check that chrome.runtime.onInstalled wasn't fired except timeout. 1. There is no way to check that chrome.runtime.onInstalled wasn't fired except timeout.
@ -214,26 +219,20 @@ chrome.storage.local.get(null, oldStorage => {
Better on each launch then on each pull. Better on each launch then on each pull.
*/ */
// LAUNCH, RELOAD, UPDATE var ifAlarmTriggered = antiCensorRu.setAlarms();
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
if (antiCensorRu.version === oldStorage.version) { if (antiCensorRu.version === oldStorage.version) {
// LAUNCH, RELOAD // LAUNCH, RELOAD
console.log('Launch or reload. Do nothing.'); antiCensorRu.pacProviders = oldStorage.pacProviders;
return cb(); return console.log('Extension launched, reloaded or enabled.');
} }
// UPDATE & MIGRATION // UPDATE & MIGRATION
console.log('Updating...'); console.log('Extension updated.');
return antiCensorRu.pacProvider && if (!ifAlarmTriggered)
updatePacProxyIps( updatePacProxyIps(
antiCensorRu.pacProvider, antiCensorRu.pacProvider,
ipsError => { ipsError => ipsError ? console.log('Error updating IPs:', ipsError) : antiCensorRu.pushToStorage()
if (ipsError) ipsError.ifNotCritical = true;
antiCensorRu.pushToStorage( pushError => cb( pushError || ipsError ) );
}
); );
/* /*
@ -261,8 +260,8 @@ function asyncLogGroup() {
var cb = args.pop(); var cb = args.pop();
console.group.apply(console, args); console.group.apply(console, args);
return function() { return function() {
console.log('Finished');
console.groupEnd(); console.groupEnd();
console.log('Group finished.');
var _cb = cb || (() => {}); var _cb = cb || (() => {});
return _cb.apply(this, arguments); return _cb.apply(this, arguments);
} }
@ -296,13 +295,15 @@ function updatePacProxyIps(provider, cb) {
errors: {} errors: {}
}; };
var i = 0; var i = 0;
for (var proxyHost of provider.proxyHosts) { provider.proxyHosts.map(
httpGet( proxyHost => httpGet(
'http://www.dns-lg.com/google1/'+ proxyHost +'/A', 'http://www.dns-lg.com/google1/'+ proxyHost +'/A',
(err, res) => { (err, res) => {
if (!err) { if (!err) {
provider.proxyIps = provider.proxyIps || {}; provider.proxyIps = provider.proxyIps || {};
provider.proxyIps[ JSON.parse(res).answer[0].rdata ] = proxyHost; JSON.parse(res).answer.map(
ans => provider.proxyIps[ ans.rdata ] = proxyHost
)
} else } else
failure.errors[proxyHost] = err; failure.errors[proxyHost] = err;
@ -311,9 +312,9 @@ function updatePacProxyIps(provider, cb) {
return cb(failure, provider.proxyIps); return cb(failure, provider.proxyIps);
} }
} }
)
); );
} }
}
function setPacScriptFromProvider(provider, cb) { function setPacScriptFromProvider(provider, cb) {
var cb = asyncLogGroup('Getting pac script from provider...', provider.pacUrl, cb); var cb = asyncLogGroup('Getting pac script from provider...', provider.pacUrl, cb);

View File

@ -1,121 +0,0 @@
'use strict';
// Shows user browserAction icon if any part of the current site is being blocked and proxied.
/*
In what moment the title of the previous icon is cleared?
By my observations it usually takes place near tabs.onUpdate of tab status to "loading".
So if you set a title earlier it may be cleared by browser.
It pertains not only to page refesh but to newly opened pages too.
Also on loosing title see:
https://github.com/ilyaigpetrov/repository-for-chrome-bugs/blob/master/browserAction-title-lost-after-setting/background.js
Crazy parallel Chrome.
**/
window.onTabUpdated = {};
chrome.tabs.onRemoved.addListener( tabId => delete window.onTabUpdated[tabId] );
function afterTabUpdated(tabId, cb) {
if (window.onTabUpdated[tabId])
window.onTabUpdated[tabId].push(cb);
else window.onTabUpdated[tabId] = [cb];
}
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (window.onTabUpdated[tabId]) {
window.onTabUpdated[tabId].map( f => f() );
delete window.onTabUpdated[tabId];
}
});
var previousUpdateTitleFinished = Promise.resolve();
function blockInform(requestDetails) {
if (requestDetails.tabId !== -1 && window.antiCensorRu.pacProvider && window.antiCensorRu.pacProvider.proxyIps && window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ]) {
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
() => new Promise(
resolve => {
var cb = () => updateTitle( requestDetails, resolve );
return requestDetails.type === 'main_frame' ? afterTabUpdated(requestDetails.tabId, cb) : cb();
}
)
);
function updateTitle(requestDetails, cb) {
chrome.browserAction.getTitle(
{ tabId: requestDetails.tabId },
title => {
var ifTitleSetAlready = /\n/.test(title);
var proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
var a = document.createElement('a');
a.href = requestDetails.url;
var hostname = a.hostname;
var ifShouldUpdateTitle = false;
var indent = ' ';
var proxyTitle = 'Прокси:';
if (!ifTitleSetAlready) {
title = 'Разблокированы:\n'+ indent + hostname +'\n'+ proxyTitle +'\n'+ indent + proxyHost;
ifShouldUpdateTitle = true;
chrome.browserAction.setBadgeText({
tabId: requestDetails.tabId,
text: requestDetails.type === 'main_frame' ? '1' : '%1'
});
} else {
var hostsProxiesPair = title.split(proxyTitle);
if (hostsProxiesPair[1].indexOf(proxyHost) === -1) {
title = title.replace(hostsProxiesPair[1], hostsProxiesPair[1] +'\n'+ indent + proxyHost);
ifShouldUpdateTitle = true;
}
if (hostsProxiesPair[0].indexOf(hostname) === -1) {
title = title.replace(proxyTitle, indent + hostname +'\n'+ proxyTitle);
ifShouldUpdateTitle = true;
var _cb = cb;
cb = () => chrome.browserAction.getBadgeText(
{tabId: requestDetails.tabId},
result => {
chrome.browserAction.setBadgeText(
{
tabId: requestDetails.tabId,
text: ( isNaN( result.charAt(0) ) && result.charAt(0) || '' ) + (hostsProxiesPair[0].split('\n').length - 1)
}
);
return _cb();
}
);
}
}
if (ifShouldUpdateTitle)
chrome.browserAction.setTitle({
title: title,
tabId: requestDetails.tabId
});
return cb();
}
);
}
}
}
chrome.webRequest.onResponseStarted.addListener(
blockInform,
{ urls: ['<all_urls>'] }
);
chrome.webRequest.onErrorOccurred.addListener(
blockInform,
{ urls: ['<all_urls>'] }
);