26
26
import cacheStorage from './cachestorage.js';
27
27
import logger from './logger.js';
28
28
import µb from './background.js';
29
+
import { ubolog } from './console.js';
29
30
import { i18n$ } from './i18n.js';
30
31
import * as sfp from './static-filtering-parser.js';
31
-
import { ubolog } from './console.js';
32
+
import { orphanizeString, } from './text-utils.js';
32
33
33
34
/******************************************************************************/
34
35
@@ -47,6 +48,8 @@ let remoteServerFriendly = false;
47
48
48
49
/******************************************************************************/
49
50
51
+
const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
52
+
50
53
const parseExpires = s => {
51
54
const matches = s.match(/(\d+)\s*([dh])?/i);
52
55
if ( matches === null ) { return 0; }
@@ -71,7 +74,7 @@ const extractMetadataFromList = (content, fields) => {
71
74
field = field.toLowerCase().replace(
72
75
/-[a-z]/g, s => s.charAt(1).toUpperCase()
73
76
);
74
-
out[field] = value;
77
+
out[field] = value && orphanizeString(value);
75
78
}
76
79
// Pre-process known fields
77
80
if ( out.lastModified ) {
@@ -169,7 +172,44 @@ const isDiffUpdatableAsset = content => {
169
172
/^[^%].*[^%]$/.test(data.diffPath);
170
173
};
171
174
172
-
const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
175
+
/******************************************************************************/
176
+
177
+
// favorLocal: avoid making network requests whenever possible
178
+
// favorOrigin: avoid using CDN URLs whenever possible
179
+
180
+
const getContentURLs = (assetKey, options = {}) => {
181
+
const contentURLs = [];
182
+
const entry = assetSourceRegistry[assetKey];
183
+
if ( entry instanceof Object === false ) { return contentURLs; }
184
+
if ( typeof entry.contentURL === 'string' ) {
185
+
contentURLs.push(entry.contentURL);
186
+
} else if ( Array.isArray(entry.contentURL) ) {
187
+
contentURLs.push(...entry.contentURL);
188
+
} else if ( reIsExternalPath.test(assetKey) ) {
189
+
contentURLs.push(assetKey);
190
+
}
191
+
if ( options.favorLocal ) {
192
+
contentURLs.sort((a, b) => {
193
+
if ( reIsExternalPath.test(a) ) { return 1; }
194
+
if ( reIsExternalPath.test(b) ) { return -1; }
195
+
return 0;
196
+
});
197
+
}
198
+
if ( Array.isArray(entry.cdnURLs) ) {
199
+
const cdnURLs = entry.cdnURLs.slice();
200
+
for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
201
+
const j = Math.floor(Math.random() * n);
202
+
if ( j === i ) { continue; }
203
+
[ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
204
+
}
205
+
if ( options.favorLocal || options.favorOrigin ) {
206
+
contentURLs.push(...cdnURLs);
207
+
} else {
208
+
contentURLs.unshift(...cdnURLs);
209
+
}
210
+
}
211
+
return contentURLs;
212
+
};
173
213
174
214
/******************************************************************************/
175
215
@@ -917,28 +957,17 @@ assets.get = async function(assetKey, options = {}) {
917
957
}
918
958
919
959
const assetRegistry = await getAssetSourceRegistry();
960
+
920
961
assetDetails = assetRegistry[assetKey] || {};
921
-
const contentURLs = [];
922
-
if ( typeof assetDetails.contentURL === 'string' ) {
923
-
contentURLs.push(assetDetails.contentURL);
924
-
} else if ( Array.isArray(assetDetails.contentURL) ) {
925
-
contentURLs.push(...assetDetails.contentURL);
926
-
} else if ( reIsExternalPath.test(assetKey) ) {
962
+
963
+
const contentURLs = getContentURLs(assetKey, options);
964
+
if ( contentURLs.length === 0 && reIsExternalPath.test(assetKey) ) {
927
965
assetDetails.content = 'filters';
928
966
contentURLs.push(assetKey);
929
967
}
930
968
931
-
// https://github.com/uBlockOrigin/uBlock-issues/issues/1566#issuecomment-826473517
932
-
// Use CDN URLs as fall back URLs.
933
-
if ( Array.isArray(assetDetails.cdnURLs) ) {
934
-
contentURLs.push(...assetDetails.cdnURLs);
935
-
}
936
-
937
969
let error = 'ENOTFOUND';
938
970
for ( const contentURL of contentURLs ) {
939
-
if ( reIsExternalPath.test(contentURL) && assetDetails.hasLocalURL ) {
940
-
continue;
941
-
}
942
971
const details = assetDetails.content === 'filters'
943
972
? await assets.fetchFilterList(contentURL)
944
973
: await assets.fetchText(contentURL);
@@ -966,7 +995,7 @@ assets.get = async function(assetKey, options = {}) {
966
995
967
996
/******************************************************************************/
968
997
969
-
async function getRemote(assetKey) {
998
+
async function getRemote(assetKey, options = {}) {
970
999
const [
971
1000
assetDetails = {},
972
1001
cacheDetails = {},
@@ -978,56 +1007,19 @@ async function getRemote(assetKey) {
978
1007
let error;
979
1008
let stale = false;
980
1009
981
-
const reportBack = function(content, err) {
982
-
const details = { assetKey, content };
983
-
if ( err ) {
1010
+
const reportBack = function(content, url = '', err = '') {
1011
+
const details = { assetKey, content, url };
1012
+
if ( err !== '') {
984
1013
details.error = assetDetails.lastError = err;
985
1014
} else {
986
1015
assetDetails.lastError = undefined;
987
1016
}
988
1017
return details;
989
1018
};
990
1019
991
-
const contentURLs = [];
992
-
if ( typeof assetDetails.contentURL === 'string' ) {
993
-
contentURLs.push(assetDetails.contentURL);
994
-
} else if ( Array.isArray(assetDetails.contentURL) ) {
995
-
contentURLs.push(...assetDetails.contentURL);
996
-
}
997
-
998
-
// If asked to be gentle on remote servers, favour using dedicated CDN
999
-
// servers. If more than one CDN server is present, randomly shuffle the
1000
-
// set of servers so as to spread the bandwidth burden.
1001
-
//
1002
-
// https://github.com/uBlockOrigin/uBlock-issues/issues/1566#issuecomment-826473517
1003
-
// In case of manual update, use CDNs URLs as fall back URLs.
1004
-
if ( Array.isArray(assetDetails.cdnURLs) ) {
1005
-
const cdnURLs = assetDetails.cdnURLs.slice();
1006
-
for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
1007
-
const j = Math.floor(Math.random() * n);
1008
-
if ( j === i ) { continue; }
1009
-
[ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
1010
-
}
1011
-
if ( remoteServerFriendly ) {
1012
-
contentURLs.unshift(...cdnURLs);
1013
-
} else {
1014
-
contentURLs.push(...cdnURLs);
1015
-
}
1016
-
}
1017
-
1018
-
for ( let contentURL of contentURLs ) {
1020
+
for ( const contentURL of getContentURLs(assetKey, options) ) {
1019
1021
if ( reIsExternalPath.test(contentURL) === false ) { continue; }
1020
1022
1021
-
// This will force uBO to fetch the proper version according to whether
1022
-
// the dev build is being used. This can be removed when execution of
1023
-
// this code path is widespread for dev build revisions of uBO.
1024
-
if ( assetKey === 'assets.json' ) {
1025
-
contentURL = contentURL.replace(
1026
-
/\/assets\/assets\.json$/,
1027
-
µb.assetsJsonPath
1028
-
);
1029
-
}
1030
-
1031
1023
const result = assetDetails.content === 'filters'
1032
1024
? await assets.fetchFilterList(contentURL)
1033
1025
: await assets.fetchText(contentURL);
@@ -1066,12 +1058,12 @@ async function getRemote(assetKey) {
1066
1058
}
1067
1059
1068
1060
registerAssetSource(assetKey, { birthtime: undefined, error: undefined });
1069
-
return reportBack(result.content);
1061
+
return reportBack(result.content, contentURL);
1070
1062
}
1071
1063
1072
1064
if ( error !== undefined ) {
1073
1065
registerAssetSource(assetKey, { error: { time: Date.now(), error } });
1074
-
return reportBack('', 'ENOTFOUND');
1066
+
return reportBack('', '', 'ENOTFOUND');
1075
1067
}
1076
1068
1077
1069
if ( stale ) {
@@ -1194,6 +1186,8 @@ const getAssetDiffDetails = assetKey => {
1194
1186
};
1195
1187
1196
1188
async function diffUpdater() {
1189
+
if ( updaterAuto === false ) { return; }
1190
+
if ( µb.hiddenSettings.differentialUpdate === false ) { return; }
1197
1191
const toUpdate = await getUpdateCandidates();
1198
1192
const now = Date.now();
1199
1193
const toHardUpdate = [];
@@ -1298,6 +1292,7 @@ async function diffUpdater() {
1298
1292
1299
1293
function updateFirst() {
1300
1294
ubolog('Updater: cycle start');
1295
+
ubolog('Updater: Fetch from ', updaterAuto ? 'CDNs' : 'origin');
1301
1296
updaterStatus = 'updating';
1302
1297
updaterFetched.clear();
1303
1298
updaterUpdated.length = 0;
@@ -1367,7 +1362,7 @@ async function updateNext() {
1367
1362
1368
1363
let result;
1369
1364
if ( assetKey !== 'assets.json' || µb.hiddenSettings.debugAssetsJson !== true ) {
1370
-
result = await getRemote(assetKey);
1365
+
result = await getRemote(assetKey, { favorOrigin: updaterAuto === false });
1371
1366
} else {
1372
1367
result = await assets.fetchText(µb.assetsJsonPath);
1373
1368
result.assetKey = 'assets.json';
@@ -1396,6 +1391,7 @@ function updateDone() {
1396
1391
updaterFetched.clear();
1397
1392
updaterUpdated.length = 0;
1398
1393
updaterStatus = undefined;
1394
+
updaterAuto = false;
1399
1395
updaterAssetDelay = updaterAssetDelayDefault;
1400
1396
ubolog('Updater: cycle end');
1401
1397
if ( assetKeys.length ) {
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4