Skip to content

Commit

Permalink
Improve prevent-xhr scriptlet
Browse files Browse the repository at this point in the history
As per filter list maintainers feedback.
  • Loading branch information
gorhill committed Aug 26, 2024
1 parent 26b2ab8 commit 3a249f3
Showing 1 changed file with 63 additions and 18 deletions.
81 changes: 63 additions & 18 deletions assets/resources/scriptlets.js
Original file line number Diff line number Diff line change
Expand Up @@ -2695,6 +2695,13 @@ function noXhrIf(
'content-type': '',
'content-length': '',
};
const safeDispatchEvent = (xhr, type) => {
try {
xhr.dispatchEvent(new Event(type));
} catch(_) {
}
};
const XHRBefore = XMLHttpRequest.prototype;
self.XMLHttpRequest = class extends self.XMLHttpRequest {
open(method, url, ...args) {
xhrInstances.delete(this);
Expand All @@ -2721,27 +2728,26 @@ function noXhrIf(
let promise = Promise.resolve({
xhr: this,
directive,
props: {
readyState: { value: 4 },
response: {
response: { value: '' },
responseText: { value: '' },
responseXML: { value: null },
responseURL: { value: haystack.url },
status: { value: 200 },
statusText: { value: 'OK' },
},
}
});
switch ( this.responseType ) {
case 'arraybuffer':
promise = promise.then(details => {
details.props.response.value = new ArrayBuffer(0);
const response = details.response;
response.response.value = new ArrayBuffer(0);
return details;
});
haystack.headers['content-type'] = 'application/octet-stream';
break;
case 'blob':
promise = promise.then(details => {
details.props.response.value = new Blob([]);
const response = details.response;
response.response.value = new Blob([]);
return details;
});
haystack.headers['content-type'] = 'application/octet-stream';
Expand All @@ -2750,17 +2756,19 @@ function noXhrIf(
promise = promise.then(details => {
const parser = new DOMParser();
const doc = parser.parseFromString('', 'text/html');
details.props.response.value = doc;
details.props.responseXML.value = doc;
const response = details.response;
response.response.value = doc;
response.responseXML.value = doc;
return details;
});
haystack.headers['content-type'] = 'text/html';
break;
}
case 'json':
promise = promise.then(details => {
details.props.response.value = {};
details.props.responseText.value = '{}';
const response = details.response;
response.response.value = {};
response.responseText.value = '{}';
return details;
});
haystack.headers['content-type'] = 'application/json';
Expand All @@ -2769,20 +2777,45 @@ function noXhrIf(
if ( directive === '' ) { break; }
promise = promise.then(details => {
return generateContentFn(details.directive).then(text => {
details.props.response.value = text;
details.props.responseText.value = text;
const response = details.response;
response.response.value = text;
response.responseText.value = text;
return details;
});
});
haystack.headers['content-type'] = 'text/plain';
break;
}
promise.then(details => {
haystack.headers['content-length'] = `${details.props.response.value}`.length;
Object.defineProperties(details.xhr, details.props);
details.xhr.dispatchEvent(new Event('readystatechange'));
details.xhr.dispatchEvent(new Event('load'));
details.xhr.dispatchEvent(new Event('loadend'));
Object.defineProperties(details.xhr, {
readyState: { value: 1, configurable: true },
});
safeDispatchEvent(details.xhr, 'readystatechange');
return details;
}).then(details => {
const response = details.response;
haystack.headers['content-length'] = `${response.response.value}`.length;
Object.defineProperties(details.xhr, {
readyState: { value: 2, configurable: true },
status: { value: 200 },
statusText: { value: 'OK' },
});
safeDispatchEvent(details.xhr, 'readystatechange');
return details;
}).then(details => {
Object.defineProperties(details.xhr, {
readyState: { value: 3, configurable: true },
});
Object.defineProperties(details.xhr, details.response);
safeDispatchEvent(details.xhr, 'readystatechange');
return details;
}).then(details => {
Object.defineProperties(details.xhr, {
readyState: { value: 4 },
});
safeDispatchEvent(details.xhr, 'readystatechange');
safeDispatchEvent(details.xhr, 'load');
safeDispatchEvent(details.xhr, 'loadend');
safe.uboLog(logPrefix, `Prevented with response:\n${details.xhr.response}`);
});
}
Expand All @@ -2809,6 +2842,18 @@ function noXhrIf(
return out.join('\r\n');
}
};
self.XMLHttpRequest.prototype.open.toString = function() {
return XHRBefore.open.toString();
};
self.XMLHttpRequest.prototype.send.toString = function() {
return XHRBefore.send.toString();
};
self.XMLHttpRequest.prototype.getResponseHeader.toString = function() {
return XHRBefore.getResponseHeader.toString();
};
self.XMLHttpRequest.prototype.getAllResponseHeaders.toString = function() {
return XHRBefore.getAllResponseHeaders.toString();
};
}

/******************************************************************************/
Expand Down

0 comments on commit 3a249f3

Please sign in to comment.