mirror of https://github.com/gorhill/uBlock.git
Fine-tune details about when differential update should kick in
Manual update of one or more lists will cause the most recent version of these lists to be fetched from the "origin" server, and since the lists from "origin" servers cannot be updated through differential update, the lists will be subsequently updated according to their `Expires` directive. When the lists are auto-updated, the "CDN" servers will be used, and as a result the lists will start to be updated trhough differential updates every 6-hour (currently). Thus it is recommended and optimal to let the lists auto-update, since you will benefit from a much shorter delay to get up-to-date lists (i.e. every 6-hour instead of every 6-day). You can force the auto-updater to fetch all the lists by clicking "Purge all caches", then restart uBO without clicking "Update". This will cause uBO to perform an emergency auto-update at restart time, after which you will have all the lists which are candidates for differential update. The "Update now" button in the "Support" pane will also cause lists to be fetched from their "origin" server.
This commit is contained in:
parent
2acf8a638d
commit
69fce3aa6e
122
src/js/assets.js
122
src/js/assets.js
|
@ -26,9 +26,10 @@
|
||||||
import cacheStorage from './cachestorage.js';
|
import cacheStorage from './cachestorage.js';
|
||||||
import logger from './logger.js';
|
import logger from './logger.js';
|
||||||
import µb from './background.js';
|
import µb from './background.js';
|
||||||
|
import { ubolog } from './console.js';
|
||||||
import { i18n$ } from './i18n.js';
|
import { i18n$ } from './i18n.js';
|
||||||
import * as sfp from './static-filtering-parser.js';
|
import * as sfp from './static-filtering-parser.js';
|
||||||
import { ubolog } from './console.js';
|
import { orphanizeString, } from './text-utils.js';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -47,6 +48,8 @@ let remoteServerFriendly = false;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
|
||||||
|
|
||||||
const parseExpires = s => {
|
const parseExpires = s => {
|
||||||
const matches = s.match(/(\d+)\s*([dh])?/i);
|
const matches = s.match(/(\d+)\s*([dh])?/i);
|
||||||
if ( matches === null ) { return 0; }
|
if ( matches === null ) { return 0; }
|
||||||
|
@ -71,7 +74,7 @@ const extractMetadataFromList = (content, fields) => {
|
||||||
field = field.toLowerCase().replace(
|
field = field.toLowerCase().replace(
|
||||||
/-[a-z]/g, s => s.charAt(1).toUpperCase()
|
/-[a-z]/g, s => s.charAt(1).toUpperCase()
|
||||||
);
|
);
|
||||||
out[field] = value;
|
out[field] = value && orphanizeString(value);
|
||||||
}
|
}
|
||||||
// Pre-process known fields
|
// Pre-process known fields
|
||||||
if ( out.lastModified ) {
|
if ( out.lastModified ) {
|
||||||
|
@ -169,7 +172,44 @@ const isDiffUpdatableAsset = content => {
|
||||||
/^[^%].*[^%]$/.test(data.diffPath);
|
/^[^%].*[^%]$/.test(data.diffPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// favorLocal: avoid making network requests whenever possible
|
||||||
|
// favorOrigin: avoid using CDN URLs whenever possible
|
||||||
|
|
||||||
|
const getContentURLs = (assetKey, options = {}) => {
|
||||||
|
const contentURLs = [];
|
||||||
|
const entry = assetSourceRegistry[assetKey];
|
||||||
|
if ( entry instanceof Object === false ) { return contentURLs; }
|
||||||
|
if ( typeof entry.contentURL === 'string' ) {
|
||||||
|
contentURLs.push(entry.contentURL);
|
||||||
|
} else if ( Array.isArray(entry.contentURL) ) {
|
||||||
|
contentURLs.push(...entry.contentURL);
|
||||||
|
} else if ( reIsExternalPath.test(assetKey) ) {
|
||||||
|
contentURLs.push(assetKey);
|
||||||
|
}
|
||||||
|
if ( options.favorLocal ) {
|
||||||
|
contentURLs.sort((a, b) => {
|
||||||
|
if ( reIsExternalPath.test(a) ) { return 1; }
|
||||||
|
if ( reIsExternalPath.test(b) ) { return -1; }
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ( Array.isArray(entry.cdnURLs) ) {
|
||||||
|
const cdnURLs = entry.cdnURLs.slice();
|
||||||
|
for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
|
||||||
|
const j = Math.floor(Math.random() * n);
|
||||||
|
if ( j === i ) { continue; }
|
||||||
|
[ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
|
||||||
|
}
|
||||||
|
if ( options.favorLocal || options.favorOrigin ) {
|
||||||
|
contentURLs.push(...cdnURLs);
|
||||||
|
} else {
|
||||||
|
contentURLs.unshift(...cdnURLs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contentURLs;
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -917,28 +957,17 @@ assets.get = async function(assetKey, options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const assetRegistry = await getAssetSourceRegistry();
|
const assetRegistry = await getAssetSourceRegistry();
|
||||||
|
|
||||||
assetDetails = assetRegistry[assetKey] || {};
|
assetDetails = assetRegistry[assetKey] || {};
|
||||||
const contentURLs = [];
|
|
||||||
if ( typeof assetDetails.contentURL === 'string' ) {
|
const contentURLs = getContentURLs(assetKey, options);
|
||||||
contentURLs.push(assetDetails.contentURL);
|
if ( contentURLs.length === 0 && reIsExternalPath.test(assetKey) ) {
|
||||||
} else if ( Array.isArray(assetDetails.contentURL) ) {
|
|
||||||
contentURLs.push(...assetDetails.contentURL);
|
|
||||||
} else if ( reIsExternalPath.test(assetKey) ) {
|
|
||||||
assetDetails.content = 'filters';
|
assetDetails.content = 'filters';
|
||||||
contentURLs.push(assetKey);
|
contentURLs.push(assetKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1566#issuecomment-826473517
|
|
||||||
// Use CDN URLs as fall back URLs.
|
|
||||||
if ( Array.isArray(assetDetails.cdnURLs) ) {
|
|
||||||
contentURLs.push(...assetDetails.cdnURLs);
|
|
||||||
}
|
|
||||||
|
|
||||||
let error = 'ENOTFOUND';
|
let error = 'ENOTFOUND';
|
||||||
for ( const contentURL of contentURLs ) {
|
for ( const contentURL of contentURLs ) {
|
||||||
if ( reIsExternalPath.test(contentURL) && assetDetails.hasLocalURL ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const details = assetDetails.content === 'filters'
|
const details = assetDetails.content === 'filters'
|
||||||
? await assets.fetchFilterList(contentURL)
|
? await assets.fetchFilterList(contentURL)
|
||||||
: await assets.fetchText(contentURL);
|
: await assets.fetchText(contentURL);
|
||||||
|
@ -966,7 +995,7 @@ assets.get = async function(assetKey, options = {}) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
async function getRemote(assetKey) {
|
async function getRemote(assetKey, options = {}) {
|
||||||
const [
|
const [
|
||||||
assetDetails = {},
|
assetDetails = {},
|
||||||
cacheDetails = {},
|
cacheDetails = {},
|
||||||
|
@ -978,9 +1007,9 @@ async function getRemote(assetKey) {
|
||||||
let error;
|
let error;
|
||||||
let stale = false;
|
let stale = false;
|
||||||
|
|
||||||
const reportBack = function(content, err) {
|
const reportBack = function(content, url = '', err = '') {
|
||||||
const details = { assetKey, content };
|
const details = { assetKey, content, url };
|
||||||
if ( err ) {
|
if ( err !== '') {
|
||||||
details.error = assetDetails.lastError = err;
|
details.error = assetDetails.lastError = err;
|
||||||
} else {
|
} else {
|
||||||
assetDetails.lastError = undefined;
|
assetDetails.lastError = undefined;
|
||||||
|
@ -988,46 +1017,9 @@ async function getRemote(assetKey) {
|
||||||
return details;
|
return details;
|
||||||
};
|
};
|
||||||
|
|
||||||
const contentURLs = [];
|
for ( const contentURL of getContentURLs(assetKey, options) ) {
|
||||||
if ( typeof assetDetails.contentURL === 'string' ) {
|
|
||||||
contentURLs.push(assetDetails.contentURL);
|
|
||||||
} else if ( Array.isArray(assetDetails.contentURL) ) {
|
|
||||||
contentURLs.push(...assetDetails.contentURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If asked to be gentle on remote servers, favour using dedicated CDN
|
|
||||||
// servers. If more than one CDN server is present, randomly shuffle the
|
|
||||||
// set of servers so as to spread the bandwidth burden.
|
|
||||||
//
|
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1566#issuecomment-826473517
|
|
||||||
// In case of manual update, use CDNs URLs as fall back URLs.
|
|
||||||
if ( Array.isArray(assetDetails.cdnURLs) ) {
|
|
||||||
const cdnURLs = assetDetails.cdnURLs.slice();
|
|
||||||
for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
|
|
||||||
const j = Math.floor(Math.random() * n);
|
|
||||||
if ( j === i ) { continue; }
|
|
||||||
[ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
|
|
||||||
}
|
|
||||||
if ( remoteServerFriendly ) {
|
|
||||||
contentURLs.unshift(...cdnURLs);
|
|
||||||
} else {
|
|
||||||
contentURLs.push(...cdnURLs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( let contentURL of contentURLs ) {
|
|
||||||
if ( reIsExternalPath.test(contentURL) === false ) { continue; }
|
if ( reIsExternalPath.test(contentURL) === false ) { continue; }
|
||||||
|
|
||||||
// This will force uBO to fetch the proper version according to whether
|
|
||||||
// the dev build is being used. This can be removed when execution of
|
|
||||||
// this code path is widespread for dev build revisions of uBO.
|
|
||||||
if ( assetKey === 'assets.json' ) {
|
|
||||||
contentURL = contentURL.replace(
|
|
||||||
/\/assets\/assets\.json$/,
|
|
||||||
µb.assetsJsonPath
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = assetDetails.content === 'filters'
|
const result = assetDetails.content === 'filters'
|
||||||
? await assets.fetchFilterList(contentURL)
|
? await assets.fetchFilterList(contentURL)
|
||||||
: await assets.fetchText(contentURL);
|
: await assets.fetchText(contentURL);
|
||||||
|
@ -1066,12 +1058,12 @@ async function getRemote(assetKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerAssetSource(assetKey, { birthtime: undefined, error: undefined });
|
registerAssetSource(assetKey, { birthtime: undefined, error: undefined });
|
||||||
return reportBack(result.content);
|
return reportBack(result.content, contentURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( error !== undefined ) {
|
if ( error !== undefined ) {
|
||||||
registerAssetSource(assetKey, { error: { time: Date.now(), error } });
|
registerAssetSource(assetKey, { error: { time: Date.now(), error } });
|
||||||
return reportBack('', 'ENOTFOUND');
|
return reportBack('', '', 'ENOTFOUND');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( stale ) {
|
if ( stale ) {
|
||||||
|
@ -1194,6 +1186,8 @@ const getAssetDiffDetails = assetKey => {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function diffUpdater() {
|
async function diffUpdater() {
|
||||||
|
if ( updaterAuto === false ) { return; }
|
||||||
|
if ( µb.hiddenSettings.differentialUpdate === false ) { return; }
|
||||||
const toUpdate = await getUpdateCandidates();
|
const toUpdate = await getUpdateCandidates();
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const toHardUpdate = [];
|
const toHardUpdate = [];
|
||||||
|
@ -1298,6 +1292,7 @@ async function diffUpdater() {
|
||||||
|
|
||||||
function updateFirst() {
|
function updateFirst() {
|
||||||
ubolog('Updater: cycle start');
|
ubolog('Updater: cycle start');
|
||||||
|
ubolog('Updater: Fetch from ', updaterAuto ? 'CDNs' : 'origin');
|
||||||
updaterStatus = 'updating';
|
updaterStatus = 'updating';
|
||||||
updaterFetched.clear();
|
updaterFetched.clear();
|
||||||
updaterUpdated.length = 0;
|
updaterUpdated.length = 0;
|
||||||
|
@ -1367,7 +1362,7 @@ async function updateNext() {
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
if ( assetKey !== 'assets.json' || µb.hiddenSettings.debugAssetsJson !== true ) {
|
if ( assetKey !== 'assets.json' || µb.hiddenSettings.debugAssetsJson !== true ) {
|
||||||
result = await getRemote(assetKey);
|
result = await getRemote(assetKey, { favorOrigin: updaterAuto === false });
|
||||||
} else {
|
} else {
|
||||||
result = await assets.fetchText(µb.assetsJsonPath);
|
result = await assets.fetchText(µb.assetsJsonPath);
|
||||||
result.assetKey = 'assets.json';
|
result.assetKey = 'assets.json';
|
||||||
|
@ -1396,6 +1391,7 @@ function updateDone() {
|
||||||
updaterFetched.clear();
|
updaterFetched.clear();
|
||||||
updaterUpdated.length = 0;
|
updaterUpdated.length = 0;
|
||||||
updaterStatus = undefined;
|
updaterStatus = undefined;
|
||||||
|
updaterAuto = false;
|
||||||
updaterAssetDelay = updaterAssetDelayDefault;
|
updaterAssetDelay = updaterAssetDelayDefault;
|
||||||
ubolog('Updater: cycle end');
|
ubolog('Updater: cycle end');
|
||||||
if ( assetKeys.length ) {
|
if ( assetKeys.length ) {
|
||||||
|
|
|
@ -49,9 +49,9 @@ const hiddenSettingsDefault = {
|
||||||
allowGenericProceduralFilters: false,
|
allowGenericProceduralFilters: false,
|
||||||
assetFetchTimeout: 30,
|
assetFetchTimeout: 30,
|
||||||
autoCommentFilterTemplate: '{{date}} {{origin}}',
|
autoCommentFilterTemplate: '{{date}} {{origin}}',
|
||||||
autoUpdateAssetFetchPeriod: 60,
|
autoUpdateAssetFetchPeriod: 15,
|
||||||
autoUpdateDelayAfterLaunch: 105,
|
autoUpdateDelayAfterLaunch: 105,
|
||||||
autoUpdatePeriod: 2,
|
autoUpdatePeriod: 1,
|
||||||
benchmarkDatasetURL: 'unset',
|
benchmarkDatasetURL: 'unset',
|
||||||
blockingProfiles: '11111/#F00 11010/#C0F 11001/#00F 00001',
|
blockingProfiles: '11111/#F00 11010/#C0F 11001/#00F 00001',
|
||||||
cacheStorageAPI: 'unset',
|
cacheStorageAPI: 'unset',
|
||||||
|
@ -69,6 +69,7 @@ const hiddenSettingsDefault = {
|
||||||
debugAssetsJson: false,
|
debugAssetsJson: false,
|
||||||
debugScriptlets: false,
|
debugScriptlets: false,
|
||||||
debugScriptletInjector: false,
|
debugScriptletInjector: false,
|
||||||
|
differentialUpdate: true,
|
||||||
disableWebAssembly: false,
|
disableWebAssembly: false,
|
||||||
extensionUpdateForceReload: false,
|
extensionUpdateForceReload: false,
|
||||||
filterAuthorMode: false,
|
filterAuthorMode: false,
|
||||||
|
|
|
@ -981,7 +981,10 @@ import {
|
||||||
return { assetKey, content: '' };
|
return { assetKey, content: '' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawDetails = await io.get(assetKey, { silent: true });
|
const rawDetails = await io.get(assetKey, {
|
||||||
|
favorLocal: this.readyToFilter !== true,
|
||||||
|
silent: true,
|
||||||
|
});
|
||||||
// Compiling an empty string results in an empty string.
|
// Compiling an empty string results in an empty string.
|
||||||
if ( rawDetails.content === '' ) {
|
if ( rawDetails.content === '' ) {
|
||||||
rawDetails.assetKey = assetKey;
|
rawDetails.assetKey = assetKey;
|
||||||
|
|
Loading…
Reference in New Issue