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

View File

@ -25,7 +25,8 @@ window.antiCensorRu = {
pacUrl: 'http://antizapret.prostovpn.org/proxy.pac',
proxyHosts: ['proxy.antizapret.prostovpn.org'],
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',
proxyHosts: ['gw2.anticenz.org', 'proxy.antizapret.prostovpn.org'],
proxyHosts: ['proxy.antizapret.prostovpn.org', 'gw2.anticenz.org'],
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) {
var cb = cb || (() => {});
var cb = asyncLogGroup('Syncing with PAC provider...', cb);
if (!this.pacProvider)
return cb({clarification: 'Сперва выберите PAC-провайдера.'});
@ -105,8 +107,11 @@ window.antiCensorRu = {
(err, res) => {
if (err)
return reject(err);
this.lastPacUpdateStamp = Date.now();
this.ifFirstInstall = false;
this.setAlarms();
return resolve(res);
}
)
@ -127,15 +132,29 @@ window.antiCensorRu = {
);
},
_pacUpdatePeriodInMinutes: 4*60,
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(
this._periodicUpdateAlarmReason,
{ periodInMinutes: 4*60 }
{
when: nextUpdateMoment,
periodInMinutes: this._pacUpdatePeriodInMinutes
}
);
return nextUpdateMoment === now; // ifAlarmTriggered. Return value may be changed.
},
installPac(key, cb) {
if(typeof(key) === 'function') {
cb = key;
key = undefined;
@ -144,12 +163,7 @@ window.antiCensorRu = {
if(key)
this.currentPacProviderKey = key;
var cb = asyncLogGroup('Installing PAC...', cb);
this.setAlarms();
return this.syncWithPacProvider(cb);
},
clearPac(cb) {
@ -171,41 +185,32 @@ window.antiCensorRu = {
chrome.storage.local.get(null, oldStorage => {
console.log('Init on storage:', oldStorage);
antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0;
// Finish each init with this callback setting alarm listeners.
function cb(err) {
if (!antiCensorRu.ifFirstInstall) {
// LAUNCH, RELOAD, UPDATE
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
}
chrome.alarms.onAlarm.addListener(
alarm => {
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();
}
}
);
console.log('Alarm listener installed. We won\'t miss any PAC update.');
chrome.alarms.get(
antiCensorRu._periodicUpdateAlarmReason,
alarm => {
if (alarm)
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.');
}
}
);
if (antiCensorRu.ifFirstInstall) {
// INSTALL
console.log('Installing...');
return chrome.runtime.openOptionsPage();
}
// INSTALL
if (antiCensorRu.ifFirstInstall) {
console.log('Installing...');
return chrome.runtime.openOptionsPage(cb);
}
if (!antiCensorRu.pacProvider)
return console.log('No PAC provider set. Do nothing.');
/*
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.
*/
// LAUNCH, RELOAD, UPDATE
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
var ifAlarmTriggered = antiCensorRu.setAlarms();
if (antiCensorRu.version === oldStorage.version) {
// LAUNCH, RELOAD
console.log('Launch or reload. Do nothing.');
return cb();
antiCensorRu.pacProviders = oldStorage.pacProviders;
return console.log('Extension launched, reloaded or enabled.');
}
// UPDATE & MIGRATION
console.log('Updating...');
return antiCensorRu.pacProvider &&
console.log('Extension updated.');
if (!ifAlarmTriggered)
updatePacProxyIps(
antiCensorRu.pacProvider,
ipsError => {
if (ipsError) ipsError.ifNotCritical = true;
antiCensorRu.pushToStorage( pushError => cb( pushError || ipsError ) );
}
ipsError => ipsError ? console.log('Error updating IPs:', ipsError) : antiCensorRu.pushToStorage()
);
/*
@ -261,8 +260,8 @@ function asyncLogGroup() {
var cb = args.pop();
console.group.apply(console, args);
return function() {
console.log('Finished');
console.groupEnd();
console.log('Group finished.');
var _cb = cb || (() => {});
return _cb.apply(this, arguments);
}
@ -296,13 +295,15 @@ function updatePacProxyIps(provider, cb) {
errors: {}
};
var i = 0;
for (var proxyHost of provider.proxyHosts) {
httpGet(
provider.proxyHosts.map(
proxyHost => httpGet(
'http://www.dns-lg.com/google1/'+ proxyHost +'/A',
(err, res) => {
if (!err) {
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
failure.errors[proxyHost] = err;
@ -311,8 +312,8 @@ function updatePacProxyIps(provider, cb) {
return cb(failure, provider.proxyIps);
}
}
)
);
}
}
function setPacScriptFromProvider(provider, 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>'] }
);