1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-06 09:37:12 +02:00
This commit is contained in:
gorhill 2016-04-20 13:57:31 -04:00
parent f1ba21b20c
commit 2d26d1dd3d
2 changed files with 168 additions and 0 deletions

View File

@ -903,8 +903,35 @@ vAPI.net.registerListeners = function() {
}
};
// https://bugs.chromium.org/p/chromium/issues/detail?id=129353
// https://github.com/gorhill/uBlock/issues/1497
// Expose websocket-based network requests to uBO's filtering engine,
// logger, etc.
// Counterpart of following block of code is found in "vapi-client.js" --
// search for "https://github.com/gorhill/uBlock/issues/1497".
var onBeforeWebsocketRequest = function(details) {
details.type = 'websocket';
var matches = /url=([^&]+)/.exec(details.url);
details.url = decodeURIComponent(matches[1]);
var r = onBeforeRequestClient(details);
// Blocked?
if ( r && r.cancel ) {
return { cancel: true };
}
// Returning a 1x1 transparent pixel means "not blocked".
return { redirectUrl: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' };
};
var onBeforeRequestClient = this.onBeforeRequest.callback;
var onBeforeRequest = function(details) {
// https://github.com/gorhill/uBlock/issues/1497
if (
details.type === 'image' &&
details.url.endsWith('ubofix=f41665f3028c7fd10eecf573336216d3')
) {
return onBeforeWebsocketRequest(details);
}
normalizeRequestDetails(details);
return onBeforeRequestClient(details);
};

View File

@ -338,6 +338,147 @@ vAPI.shutdown.add(function() {
// https://www.youtube.com/watch?v=rT5zCHn0tsg
// https://www.youtube.com/watch?v=E-jS4e3zacI
/******************************************************************************/
// https://bugs.chromium.org/p/chromium/issues/detail?id=129353
// https://github.com/gorhill/uBlock/issues/1497
// Trap calls to WebSocket constructor, and expose websocket-based network
// requests to uBO's filtering engine, logger, etc.
// Counterpart of following block of code is found in "vapi-background.js" --
// search for "https://github.com/gorhill/uBlock/issues/1497".
(function() {
// Only for http/https documents.
if ( /^https?:/.test(window.location.protocol) !== true ) {
return;
}
var doc = document;
var parent = doc.head || doc.documentElement;
if ( parent === null ) {
return;
}
var WebSocketWrapper = function() {
var WS = window.WebSocket;
var onClose = function(ev) {
this.readyState = this.wrapped.readyState;
if ( this.onclose !== null ) {
this.onclose(ev);
}
};
var onError = function(ev) {
this.readyState = this.wrapped.readyState;
if ( this.onerror !== null ) {
this.onerror(ev);
}
};
var onMessage = function(ev) {
if ( this.onmessage !== null ) {
this.onmessage(ev);
}
};
var onOpen = function(ev) {
this.readyState = this.wrapped.readyState;
if ( this.onopen !== null ) {
this.onopen(ev);
}
};
var onAllowed = function(ws, url, protocols) {
this.removeEventListener('load', onAllowed);
this.removeEventListener('error', onBlocked);
connect(ws, url, protocols);
};
var onBlocked = function(ws) {
this.removeEventListener('load', onAllowed);
this.removeEventListener('error', onBlocked);
if ( ws.onerror !== null ) {
ws.onerror(new window.ErrorEvent('error'));
}
};
var connect = function(ws, url, protocols) {
ws.wrapped = new WS(url, protocols);
ws.wrapped.onclose = onClose.bind(ws);
ws.wrapped.onerror = onError.bind(ws);
ws.wrapped.onmessage = onMessage.bind(ws);
ws.wrapped.onopen = onOpen.bind(ws);
};
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
var wrapper = function(url, protocols) {
this.binaryType = '';
this.bufferedAmount = 0;
this.extensions = '';
this.onclose = null;
this.onerror = null;
this.onmessage = null;
this.onopen = null;
this.protocol = '';
this.readyState = this.CONNECTING;
this.url = url;
this.wrapped = null;
if ( /^wss?:\/\//.test(url) === false ) {
connect(this, url, protocols);
return;
}
// We will use an image network request to communicate with uBO's
// main process.
var img = new Image();
img.src = [
window.location.origin,
'?url=' + encodeURIComponent(url),
'&ubofix=f41665f3028c7fd10eecf573336216d3'
].join('');
img.addEventListener('load', onAllowed.bind(img, this, url, protocols));
img.addEventListener('error', onBlocked.bind(img, this, url, protocols));
};
wrapper.prototype.close = function(code, reason) {
if ( this.wrapped !== null ) {
this.wrapped.close(code, reason);
}
};
wrapper.prototype.send = function(data) {
if ( this.wrapped !== null ) {
this.wrapped.send(data);
}
};
wrapper.prototype.CONNECTING = 0;
wrapper.prototype.OPEN = 1;
wrapper.prototype.CLOSING = 2;
wrapper.prototype.CLOSED = 3;
window.WebSocket = wrapper;
// Remove our own tag to avoid polluting document.
var me = document.getElementById('ubofix-f41665f3028c7fd10eecf573336216d3');
if ( me !== null && me.parentNode !== null ) {
me.parentNode.removeChild(me);
}
};
// The script tag will remove itself from the DOM once it completes
// execution.
var script = doc.createElement('script');
script.id = 'ubofix-f41665f3028c7fd10eecf573336216d3';
script.textContent = '(' + WebSocketWrapper.toString() + ')();';
try {
parent.appendChild(script);
} catch (ex) {
}
})();
/******************************************************************************/
/******************************************************************************/