mirror of https://github.com/gorhill/uBlock.git
this fixes #276
This commit is contained in:
parent
1a679240fb
commit
6fd9da22bc
|
@ -9,7 +9,6 @@
|
||||||
<script src="lib/publicsuffixlist.min.js"></script>
|
<script src="lib/publicsuffixlist.min.js"></script>
|
||||||
<script src="lib/yamd5.js"></script>
|
<script src="lib/yamd5.js"></script>
|
||||||
<script src="js/background.js"></script>
|
<script src="js/background.js"></script>
|
||||||
<script src="js/mirrors.js"></script>
|
|
||||||
<script src="js/xal.js"></script>
|
<script src="js/xal.js"></script>
|
||||||
<script src="js/async.js"></script>
|
<script src="js/async.js"></script>
|
||||||
<script src="js/liquid-dict.js"></script>
|
<script src="js/liquid-dict.js"></script>
|
||||||
|
@ -27,6 +26,7 @@
|
||||||
<script src="js/traffic.js"></script>
|
<script src="js/traffic.js"></script>
|
||||||
<script src="js/messaging-handlers.js"></script>
|
<script src="js/messaging-handlers.js"></script>
|
||||||
<script src="js/contextmenu.js"></script>
|
<script src="js/contextmenu.js"></script>
|
||||||
|
<script src="js/mirrors.js"></script>
|
||||||
<script src="js/start.js"></script>
|
<script src="js/start.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
130
js/mirrors.js
130
js/mirrors.js
|
@ -41,6 +41,7 @@ var exports = {
|
||||||
bytesInUseMax: 5 * 1024 * 1024,
|
bytesInUseMax: 5 * 1024 * 1024,
|
||||||
ttl: 21 * 24 * 60 * 60 * 1000,
|
ttl: 21 * 24 * 60 * 60 * 1000,
|
||||||
bytesInUse: 0,
|
bytesInUse: 0,
|
||||||
|
tryCount: 0,
|
||||||
hitCount: 0
|
hitCount: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,22 +51,9 @@ var nullFunc = function() {};
|
||||||
|
|
||||||
// TODO: need to come up with something better. Key shoud be domain. More
|
// TODO: need to come up with something better. Key shoud be domain. More
|
||||||
// control over what significant part(s) of a URL is to be used as key.
|
// control over what significant part(s) of a URL is to be used as key.
|
||||||
var mirrorCandidates = {
|
var mirrorCandidates = Object.create(null);
|
||||||
'ajax.googleapis.com': /^ajax\.googleapis\.com\/ajax\/libs\//,
|
|
||||||
'fonts.googleapis.com': /^fonts\.googleapis\.com/,
|
|
||||||
'fonts.gstatic.com': /^fonts\.gstatic\.com/,
|
|
||||||
'cdnjs.cloudflare.com': /^cdnjs\.cloudflare\.com\/ajax\/libs\//,
|
|
||||||
'code.jquery.com': /^code\.jquery\.com/,
|
|
||||||
's0.2mdn.net': /(2mdn\.net\/instream\/html5\/ima3\.js)/,
|
|
||||||
'www.googletagservices.com': /(www\.googletagservices\.com\/tag\/js\/gpt\.js)/,
|
|
||||||
'maxcdn.bootstrapcdn.com': /^maxcdn\.bootstrapcdn\.com\/font-awesome\//,
|
|
||||||
'netdna.bootstrapcdn.com': /^netdna\.bootstrapcdn\.com\/bootstrap\//,
|
|
||||||
'b.scorecardresearch.com': /^b\.scorecardresearch\.com\/beacon\.js/,
|
|
||||||
'platform.twitter.com': /^platform\.twitter\.com\/widgets\.js/,
|
|
||||||
'cdn.quilt.janrain.com': /^cdn\.quilt\.janrain\.com\//
|
|
||||||
};
|
|
||||||
|
|
||||||
var magicId = 'rmwwgwkzcgfv';
|
var magicId = 'zicibucpobdu';
|
||||||
var metadataPersistTimer = null;
|
var metadataPersistTimer = null;
|
||||||
var bytesInUseMercy = 1 * 1024 * 1024;
|
var bytesInUseMercy = 1 * 1024 * 1024;
|
||||||
|
|
||||||
|
@ -107,12 +95,12 @@ var getTextFileFromURL = function(url, onLoad, onError) {
|
||||||
onError = onLoad;
|
onError = onLoad;
|
||||||
}
|
}
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.responseType = 'text';
|
|
||||||
xhr.timeout = 10000;
|
xhr.timeout = 10000;
|
||||||
xhr.onload = onLoad;
|
xhr.onload = onLoad;
|
||||||
xhr.onerror = onError;
|
xhr.onerror = onError;
|
||||||
xhr.ontimeout = onError;
|
xhr.ontimeout = onError;
|
||||||
xhr.open('get', url, true);
|
xhr.open('get', url, true);
|
||||||
|
xhr.responseType = 'arraybuffer';
|
||||||
xhr.send();
|
xhr.send();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,9 +129,9 @@ var btoaSafe = function(input) {
|
||||||
var n = Math.floor(input.length / 3) * 3;
|
var n = Math.floor(input.length / 3) * 3;
|
||||||
var b1, b2, b3;
|
var b1, b2, b3;
|
||||||
for ( var ii = 0; ii < n; ii += 3 ) {
|
for ( var ii = 0; ii < n; ii += 3 ) {
|
||||||
b1 = input.charCodeAt(ii );
|
b1 = input[ii ];
|
||||||
b2 = input.charCodeAt(ii+1);
|
b2 = input[ii+1];
|
||||||
b3 = input.charCodeAt(ii+2);
|
b3 = input[ii+2];
|
||||||
output.push(String.fromCharCode(
|
output.push(String.fromCharCode(
|
||||||
bamap[ b1 >>> 2],
|
bamap[ b1 >>> 2],
|
||||||
bamap[(b1 & 0x03) << 4 | b2 >>> 4],
|
bamap[(b1 & 0x03) << 4 | b2 >>> 4],
|
||||||
|
@ -154,8 +142,8 @@ var btoaSafe = function(input) {
|
||||||
// Leftover
|
// Leftover
|
||||||
var m = input.length - n;
|
var m = input.length - n;
|
||||||
if ( m > 1 ) {
|
if ( m > 1 ) {
|
||||||
b1 = input.charCodeAt(ii );
|
b1 = input[ii ];
|
||||||
b2 = input.charCodeAt(ii+1);
|
b2 = input[ii+1];
|
||||||
output.push(String.fromCharCode(
|
output.push(String.fromCharCode(
|
||||||
bamap[ b1 >>> 2],
|
bamap[ b1 >>> 2],
|
||||||
bamap[(b1 & 0x03) << 4 | b2 >>> 4],
|
bamap[(b1 & 0x03) << 4 | b2 >>> 4],
|
||||||
|
@ -163,7 +151,7 @@ var btoaSafe = function(input) {
|
||||||
0x3D
|
0x3D
|
||||||
));
|
));
|
||||||
} else if ( m !== 0 ) {
|
} else if ( m !== 0 ) {
|
||||||
b1 = input.charCodeAt(ii);
|
b1 = input[ii ];
|
||||||
output.push(String.fromCharCode(
|
output.push(String.fromCharCode(
|
||||||
bamap[ b1 >>>2],
|
bamap[ b1 >>>2],
|
||||||
bamap[(b1 & 0x03) << 4 ],
|
bamap[(b1 & 0x03) << 4 ],
|
||||||
|
@ -191,36 +179,29 @@ var toUrlKey = function(url) {
|
||||||
if ( pos === -1 ) {
|
if ( pos === -1 ) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
var re = mirrorCandidates[url.slice(0, pos)];
|
var regexes = mirrorCandidates[url.slice(0, pos)];
|
||||||
if ( typeof re !== 'object' || typeof re.exec !== 'function' ) {
|
if ( regexes === undefined ) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
var matches = re.exec(url);
|
var i = regexes.length;
|
||||||
|
var matches;
|
||||||
|
while ( i-- ) {
|
||||||
|
matches = regexes[i].exec(url);
|
||||||
if ( matches === null ) {
|
if ( matches === null ) {
|
||||||
return '';
|
continue;
|
||||||
}
|
}
|
||||||
return matches.length === 1 ? url : matches[1];
|
return matches.length === 1 ? matches[0] : matches[1];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Ref: http://www.iana.org/assignments/media-types/media-types.xhtml
|
// Ref: http://www.iana.org/assignments/media-types/media-types.xhtml
|
||||||
|
|
||||||
var normalizeContentType = function(ctin) {
|
var extractMimeType = function(ctin) {
|
||||||
var ctout;
|
|
||||||
var encoding;
|
|
||||||
var pos = ctin.indexOf(';');
|
var pos = ctin.indexOf(';');
|
||||||
if ( pos === -1 ) {
|
return pos === -1 ? ctin.trim() : ctin.slice(0, pos).trim();
|
||||||
ctout = ctin.trim();
|
|
||||||
encoding = '';
|
|
||||||
} else {
|
|
||||||
ctout = ctin.slice(0, pos).trim();
|
|
||||||
encoding = ctin.slice(pos + 1).trim();
|
|
||||||
}
|
|
||||||
if ( encoding !== '' ) {
|
|
||||||
ctout += ';' + encoding;
|
|
||||||
}
|
|
||||||
return ctout;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -378,13 +359,9 @@ var cacheAsset = function(url) {
|
||||||
if ( this.status !== 200 ) {
|
if ( this.status !== 200 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var contentType = normalizeContentType(this.getResponseHeader('Content-Type'));
|
var mimeType = extractMimeType(this.getResponseHeader('Content-Type'));
|
||||||
if ( contentType === '' ) {
|
|
||||||
//console.debug('mirrors.cacheAsset(): no good content type available');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var yamd5 = new YaMD5();
|
var yamd5 = new YaMD5();
|
||||||
yamd5.appendAsciiStr(contentType);
|
yamd5.appendAsciiStr(mimeType);
|
||||||
yamd5.appendAsciiStr(this.response);
|
yamd5.appendAsciiStr(this.response);
|
||||||
var hash = yamd5.end();
|
var hash = yamd5.end();
|
||||||
addMetadata(urlKey, hash);
|
addMetadata(urlKey, hash);
|
||||||
|
@ -397,16 +374,13 @@ var cacheAsset = function(url) {
|
||||||
// as the result is somewhat more compact I believe
|
// as the result is somewhat more compact I believe
|
||||||
var dataUrl = null;
|
var dataUrl = null;
|
||||||
try {
|
try {
|
||||||
dataUrl = contentType.indexOf(';') !== -1 ?
|
dataUrl = 'data:' + mimeType + ';base64,' + btoaSafe(new Uint8Array(this.response));
|
||||||
'data:' + contentType + ',' + encodeURIComponent(this.responseText) :
|
|
||||||
'data:' + contentType + ';base64,' + btoa(this.response);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//console.debug(e);
|
//console.debug('"%s":', url, e);
|
||||||
}
|
|
||||||
if ( dataUrl === null ) {
|
|
||||||
dataUrl = 'data:' + contentType + ';base64,' + btoaSafe(this.response);
|
|
||||||
}
|
}
|
||||||
|
if ( dataUrl !== null ) {
|
||||||
addContent(hash, dataUrl);
|
addContent(hash, dataUrl);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var onRemoteAssetError = function() {
|
var onRemoteAssetError = function() {
|
||||||
|
@ -423,6 +397,7 @@ var cacheAsset = function(url) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var toURL = function(url, cache) {
|
var toURL = function(url, cache) {
|
||||||
|
exports.tryCount += 1;
|
||||||
var urlKey = toUrlKey(url);
|
var urlKey = toUrlKey(url);
|
||||||
if ( urlKey === '' ) {
|
if ( urlKey === '' ) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -449,9 +424,50 @@ var toURL = function(url, cache) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var parseMirrorCandidates = function(rawText) {
|
||||||
|
var rawTextEnd = rawText.length;
|
||||||
|
var lineBeg = 0, lineEnd;
|
||||||
|
var line;
|
||||||
|
var key = '', re;
|
||||||
|
while ( lineBeg < rawTextEnd ) {
|
||||||
|
lineEnd = rawText.indexOf('\n', lineBeg);
|
||||||
|
if ( lineEnd === -1 ) {
|
||||||
|
lineEnd = rawText.indexOf('\r', lineBeg);
|
||||||
|
if ( lineEnd === -1 ) {
|
||||||
|
lineEnd = rawTextEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = rawText.slice(lineBeg, lineEnd);
|
||||||
|
lineBeg = lineEnd + 1;
|
||||||
|
if ( line.charAt(0) === '#' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( line.charAt(0) !== ' ' ) {
|
||||||
|
key = line.trim();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( key === '' ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
re = new RegExp(line.trim());
|
||||||
|
if ( mirrorCandidates[key] === undefined ) {
|
||||||
|
mirrorCandidates[key] = [];
|
||||||
|
}
|
||||||
|
mirrorCandidates[key].push(re);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
var load = function() {
|
var load = function() {
|
||||||
loaded = true;
|
loaded = true;
|
||||||
|
|
||||||
|
var onMirrorCandidatesReady = function(details) {
|
||||||
|
if ( details.content !== '' ) {
|
||||||
|
parseMirrorCandidates(details.content);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var loadContent = function(urlKey, hash) {
|
var loadContent = function(urlKey, hash) {
|
||||||
var binKey = storageKeyFromHash(hash);
|
var binKey = storageKeyFromHash(hash);
|
||||||
var onContentReady = function(bin) {
|
var onContentReady = function(bin) {
|
||||||
|
@ -471,6 +487,7 @@ var load = function() {
|
||||||
var onMetadataReady = function(bin) {
|
var onMetadataReady = function(bin) {
|
||||||
//console.debug('mirrors.load(): loaded metadata');
|
//console.debug('mirrors.load(): loaded metadata');
|
||||||
metadata = bin.mirrors_metadata;
|
metadata = bin.mirrors_metadata;
|
||||||
|
var mustReset = metadata.magicId !== magicId;
|
||||||
var toRemove = [];
|
var toRemove = [];
|
||||||
var u2hmap = metadata.urlKeyToHashMap;
|
var u2hmap = metadata.urlKeyToHashMap;
|
||||||
var hash;
|
var hash;
|
||||||
|
@ -479,7 +496,7 @@ var load = function() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
hash = u2hmap[urlKey].hash;
|
hash = u2hmap[urlKey].hash;
|
||||||
if ( metadata.magicId !== magicId ) {
|
if ( mustReset ) {
|
||||||
toRemove.push(storageKeyFromHash(hash));
|
toRemove.push(storageKeyFromHash(hash));
|
||||||
removeMetadata(urlKey);
|
removeMetadata(urlKey);
|
||||||
continue;
|
continue;
|
||||||
|
@ -493,12 +510,13 @@ var load = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.storage.local.get({ 'mirrors_metadata': metadata }, onMetadataReady);
|
chrome.storage.local.get({ 'mirrors_metadata': metadata }, onMetadataReady);
|
||||||
|
µBlock.assets.get('assets/ublock/mirror-candidates.txt', onMirrorCandidatesReady);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var unload = function() {
|
var unload = function() {
|
||||||
updateMetadataNow();
|
pruneToSize(0);
|
||||||
metadata.urlKeyToHashMap = {};
|
metadata.urlKeyToHashMap = {};
|
||||||
hashToContentMap = {};
|
hashToContentMap = {};
|
||||||
exports.bytesInUse = 0;
|
exports.bytesInUse = 0;
|
||||||
|
|
Loading…
Reference in New Issue