1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-10-06 09:37:12 +02:00

Improve no-xhr-if scriptlet

Related issue:
https://github.com/uBlockOrigin/uBlock-issues/issues/2518
This commit is contained in:
Raymond Hill 2023-12-10 15:21:29 -05:00
parent afcefb4b35
commit d01ad24291
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -2351,12 +2351,18 @@ function noXhrIf(
const propNeedles = parsePropertiesToMatch(propsToMatch, 'url'); const propNeedles = parsePropertiesToMatch(propsToMatch, 'url');
const log = propNeedles.size === 0 ? console.log.bind(console) : undefined; const log = propNeedles.size === 0 ? console.log.bind(console) : undefined;
const warOrigin = scriptletGlobals.get('warOrigin'); const warOrigin = scriptletGlobals.get('warOrigin');
const headers = {
'date': '',
'content-type': '',
'content-length': '',
};
self.XMLHttpRequest = class extends self.XMLHttpRequest { self.XMLHttpRequest = class extends self.XMLHttpRequest {
open(method, url, ...args) { open(method, url, ...args) {
if ( log !== undefined ) { if ( log !== undefined ) {
log(`uBO: xhr.open(${method}, ${url}, ${args.join(', ')})`); log(`uBO: xhr.open(${method}, ${url}, ${args.join(', ')})`);
return super.open(method, url, ...args); return super.open(method, url, ...args);
} }
xhrInstances.delete(this);
if ( warOrigin !== undefined && url.startsWith(warOrigin) ) { if ( warOrigin !== undefined && url.startsWith(warOrigin) ) {
return super.open(method, url, ...args); return super.open(method, url, ...args);
} }
@ -2364,6 +2370,7 @@ function noXhrIf(
if ( matchObjectProperties(propNeedles, haystack) ) { if ( matchObjectProperties(propNeedles, haystack) ) {
xhrInstances.set(this, haystack); xhrInstances.set(this, haystack);
} }
haystack.headers = Object.assign({}, headers);
return super.open(method, url, ...args); return super.open(method, url, ...args);
} }
send(...args) { send(...args) {
@ -2371,6 +2378,7 @@ function noXhrIf(
if ( haystack === undefined ) { if ( haystack === undefined ) {
return super.send(...args); return super.send(...args);
} }
haystack.headers['date'] = (new Date()).toUTCString();
let promise = Promise.resolve({ let promise = Promise.resolve({
xhr: this, xhr: this,
directive, directive,
@ -2390,12 +2398,14 @@ function noXhrIf(
details.props.response.value = new ArrayBuffer(0); details.props.response.value = new ArrayBuffer(0);
return details; return details;
}); });
haystack.headers['content-type'] = 'application/octet-stream';
break; break;
case 'blob': case 'blob':
promise = promise.then(details => { promise = promise.then(details => {
details.props.response.value = new Blob([]); details.props.response.value = new Blob([]);
return details; return details;
}); });
haystack.headers['content-type'] = 'application/octet-stream';
break; break;
case 'document': { case 'document': {
promise = promise.then(details => { promise = promise.then(details => {
@ -2405,6 +2415,7 @@ function noXhrIf(
details.props.responseXML.value = doc; details.props.responseXML.value = doc;
return details; return details;
}); });
haystack.headers['content-type'] = 'text/html';
break; break;
} }
case 'json': case 'json':
@ -2413,6 +2424,7 @@ function noXhrIf(
details.props.responseText.value = '{}'; details.props.responseText.value = '{}';
return details; return details;
}); });
haystack.headers['content-type'] = 'application/json';
break; break;
default: default:
if ( directive === '' ) { break; } if ( directive === '' ) { break; }
@ -2423,15 +2435,39 @@ function noXhrIf(
return details; return details;
}); });
}); });
haystack.headers['content-type'] = 'text/plain';
break; break;
} }
promise.then(details => { promise.then(details => {
haystack.headers['content-length'] = `${details.props.response.value}`.length;
Object.defineProperties(details.xhr, details.props); Object.defineProperties(details.xhr, details.props);
details.xhr.dispatchEvent(new Event('readystatechange')); details.xhr.dispatchEvent(new Event('readystatechange'));
details.xhr.dispatchEvent(new Event('load')); details.xhr.dispatchEvent(new Event('load'));
details.xhr.dispatchEvent(new Event('loadend')); details.xhr.dispatchEvent(new Event('loadend'));
}); });
} }
getResponseHeader(headerName) {
const haystack = xhrInstances.get(this);
if ( haystack === undefined || this.readyState < this.HEADERS_RECEIVED ) {
return super.getResponseHeader(headerName);
}
const value = haystack.headers[headerName.toLowerCase()];
if ( value !== undefined && value !== '' ) { return value; }
return null;
}
getAllResponseHeaders() {
const haystack = xhrInstances.get(this);
if ( haystack === undefined || this.readyState < this.HEADERS_RECEIVED ) {
return super.getAllResponseHeaders();
}
const out = [];
for ( const [ name, value ] of Object.entries(haystack.headers) ) {
if ( !value ) { continue; }
out.push(`${name}: ${value}`);
}
if ( out.length !== 0 ) { out.push(''); }
return out.join('\r\n');
}
}; };
} }