2626import cacheStorage from './cachestorage.js' ;
2727import logger from './logger.js' ;
2828import µb from './background.js' ;
29+ import { ubolog } from './console.js' ;
2930import { i18n$ } from './i18n.js' ;
3031import * as sfp from './static-filtering-parser.js' ;
31- import { ubolog } from './console .js' ;
32+ import { orphanizeString , } from './text-utils .js' ;
3233
3334/******************************************************************************/
3435
@@ -47,6 +48,8 @@ let remoteServerFriendly = false;
4748
4849/******************************************************************************/
4950
51+ const stringIsNotEmpty = s => typeof s === 'string' && s !== '' ;
52+
5053const parseExpires = s => {
5154 const matches = s . match ( / ( \d + ) \s * ( [ d h ] ) ? / i) ;
5255 if ( matches === null ) { return 0 ; }
@@ -71,7 +74,7 @@ const extractMetadataFromList = (content, fields) => {
7174 field = field . toLowerCase ( ) . replace (
7275 / - [ a - z ] / g, s => s . charAt ( 1 ) . toUpperCase ( )
7376 ) ;
74- out [ field ] = value ;
77+ out [ field ] = value && orphanizeString ( value ) ;
7578 }
7679 // Pre-process known fields
7780 if ( out . lastModified ) {
@@ -169,7 +172,44 @@ const isDiffUpdatableAsset = content => {
169172 / ^ [ ^ % ] .* [ ^ % ] $ / . test ( data . diffPath ) ;
170173} ;
171174
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+ } ;
173213
174214/******************************************************************************/
175215
@@ -917,28 +957,17 @@ assets.get = async function(assetKey, options = {}) {
917957 }
918958
919959 const assetRegistry = await getAssetSourceRegistry ( ) ;
960+
920961 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 ) ) {
927965 assetDetails . content = 'filters' ;
928966 contentURLs . push ( assetKey ) ;
929967 }
930968
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-
937969 let error = 'ENOTFOUND' ;
938970 for ( const contentURL of contentURLs ) {
939- if ( reIsExternalPath . test ( contentURL ) && assetDetails . hasLocalURL ) {
940- continue ;
941- }
942971 const details = assetDetails . content === 'filters'
943972 ? await assets . fetchFilterList ( contentURL )
944973 : await assets . fetchText ( contentURL ) ;
@@ -966,7 +995,7 @@ assets.get = async function(assetKey, options = {}) {
966995
967996/******************************************************************************/
968997
969- async function getRemote ( assetKey ) {
998+ async function getRemote ( assetKey , options = { } ) {
970999 const [
9711000 assetDetails = { } ,
9721001 cacheDetails = { } ,
@@ -978,56 +1007,19 @@ async function getRemote(assetKey) {
9781007 let error ;
9791008 let stale = false ;
9801009
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 !== '' ) {
9841013 details . error = assetDetails . lastError = err ;
9851014 } else {
9861015 assetDetails . lastError = undefined ;
9871016 }
9881017 return details ;
9891018 } ;
9901019
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 ) ) {
10191021 if ( reIsExternalPath . test ( contentURL ) === false ) { continue ; }
10201022
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- / \/ a s s e t s \/ a s s e t s \. j s o n $ / ,
1027- µb . assetsJsonPath
1028- ) ;
1029- }
1030-
10311023 const result = assetDetails . content === 'filters'
10321024 ? await assets . fetchFilterList ( contentURL )
10331025 : await assets . fetchText ( contentURL ) ;
@@ -1066,12 +1058,12 @@ async function getRemote(assetKey) {
10661058 }
10671059
10681060 registerAssetSource ( assetKey , { birthtime : undefined , error : undefined } ) ;
1069- return reportBack ( result . content ) ;
1061+ return reportBack ( result . content , contentURL ) ;
10701062 }
10711063
10721064 if ( error !== undefined ) {
10731065 registerAssetSource ( assetKey , { error : { time : Date . now ( ) , error } } ) ;
1074- return reportBack ( '' , 'ENOTFOUND' ) ;
1066+ return reportBack ( '' , '' , ' ENOTFOUND') ;
10751067 }
10761068
10771069 if ( stale ) {
@@ -1194,6 +1186,8 @@ const getAssetDiffDetails = assetKey => {
11941186} ;
11951187
11961188async function diffUpdater ( ) {
1189+ if ( updaterAuto === false ) { return ; }
1190+ if ( µb . hiddenSettings . differentialUpdate === false ) { return ; }
11971191 const toUpdate = await getUpdateCandidates ( ) ;
11981192 const now = Date . now ( ) ;
11991193 const toHardUpdate = [ ] ;
@@ -1298,6 +1292,7 @@ async function diffUpdater() {
12981292
12991293function updateFirst ( ) {
13001294 ubolog ( 'Updater: cycle start' ) ;
1295+ ubolog ( 'Updater: Fetch from ' , updaterAuto ? 'CDNs' : 'origin' ) ;
13011296 updaterStatus = 'updating' ;
13021297 updaterFetched . clear ( ) ;
13031298 updaterUpdated . length = 0 ;
@@ -1367,7 +1362,7 @@ async function updateNext() {
13671362
13681363 let result ;
13691364 if ( assetKey !== 'assets.json' || µb . hiddenSettings . debugAssetsJson !== true ) {
1370- result = await getRemote ( assetKey ) ;
1365+ result = await getRemote ( assetKey , { favorOrigin : updaterAuto === false } ) ;
13711366 } else {
13721367 result = await assets . fetchText ( µb . assetsJsonPath ) ;
13731368 result . assetKey = 'assets.json' ;
@@ -1396,6 +1391,7 @@ function updateDone() {
13961391 updaterFetched . clear ( ) ;
13971392 updaterUpdated . length = 0 ;
13981393 updaterStatus = undefined ;
1394+ updaterAuto = false ;
13991395 updaterAssetDelay = updaterAssetDelayDefault ;
14001396 ubolog ( 'Updater: cycle end' ) ;
14011397 if ( assetKeys . length ) {
0 commit comments