Improve prevent-fetch scriptlet · gorhill/uBlock@e785b99 (original) (raw)
`@@ -57,6 +57,7 @@ function safeSelf() {
`
57
57
`'Math_random': Math.random,
`
58
58
`'Object': Object,
`
59
59
`'Object_defineProperty': Object.defineProperty.bind(Object),
`
``
60
`+
'Object_defineProperties': Object.defineProperties.bind(Object),
`
60
61
`'Object_fromEntries': Object.fromEntries.bind(Object),
`
61
62
`'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
`
62
63
`'RegExp': self.RegExp,
`
`@@ -2067,11 +2068,11 @@ builtinScriptlets.push({
`
2067
2068
`});
`
2068
2069
`function noFetchIf(
`
2069
2070
`propsToMatch = '',
`
2070
``
`-
responseBody = ''
`
``
2071
`+
responseBody = '',
`
``
2072
`+
responseType = ''
`
2071
2073
`) {
`
2072
``
`-
if ( typeof propsToMatch !== 'string' ) { return; }
`
2073
2074
`const safe = safeSelf();
`
2074
``
`-
const logPrefix = safe.makeLogPrefix('prevent-fetch', propsToMatch, responseBody);
`
``
2075
`+
const logPrefix = safe.makeLogPrefix('prevent-fetch', propsToMatch, responseBody, responseType);
`
2075
2076
`const needles = [];
`
2076
2077
`for ( const condition of propsToMatch.split(/\s+/) ) {
`
2077
2078
`if ( condition === '' ) { continue; }
`
`@@ -2086,6 +2087,26 @@ function noFetchIf(
`
2086
2087
`}
`
2087
2088
`needles.push({ key, re: safe.patternToRegex(value) });
`
2088
2089
`}
`
``
2090
`+
const validResponseProps = {
`
``
2091
`+
ok: [ false, true ],
`
``
2092
`+
type: [ 'basic', 'cors', 'opaque' ],
`
``
2093
`+
};
`
``
2094
`+
let responseProps;
`
``
2095
`+
if ( /^{.*}$/.test(responseType) ) {
`
``
2096
`+
responseProps = {};
`
``
2097
`+
try {
`
``
2098
`+
Object.entries(JSON.parse(responseType)).forEach(([ p, v ]) => {
`
``
2099
`+
if ( validResponseProps[p] === undefined ) { return; }
`
``
2100
`+
if ( validResponseProps[p].includes(v) === false ) { return; }
`
``
2101
`+
responseProps[p] = { value: v };
`
``
2102
`+
});
`
``
2103
`+
}
`
``
2104
`+
catch(ex) {}
`
``
2105
`+
} else if ( responseType !== '' ) {
`
``
2106
`+
if ( validResponseProps.type.includes(responseType) ) {
`
``
2107
`+
responseProps = { type: { value: responseType } };
`
``
2108
`+
}
`
``
2109
`+
}
`
2089
2110
`self.fetch = new Proxy(self.fetch, {
`
2090
2111
`apply: function(target, thisArg, args) {
`
2091
2112
`const details = args[0] instanceof self.Request
`
`@@ -2123,17 +2144,6 @@ function noFetchIf(
`
2123
2144
`if ( proceed ) {
`
2124
2145
`return Reflect.apply(target, thisArg, args);
`
2125
2146
`}
`
2126
``
`-
let responseType = '';
`
2127
``
`-
if ( details.mode === undefined || details.mode === 'cors' ) {
`
2128
``
`-
try {
`
2129
``
`-
const desURL = new URL(details.url);
`
2130
``
`-
responseType = desURL.origin !== document.location.origin
`
2131
``
`-
? 'cors'
`
2132
``
`-
: 'basic';
`
2133
``
`-
} catch(ex) {
`
2134
``
`` -
safe.uboErr(logPrefix, Error: ${ex});
``
2135
``
`-
}
`
2136
``
`-
}
`
2137
2147
`return generateContentFn(responseBody).then(text => {
`
2138
2148
`` safe.uboLog(logPrefix, Prevented with response "${text}");
``
2139
2149
`const response = new Response(text, {
`
`@@ -2142,14 +2152,11 @@ function noFetchIf(
`
2142
2152
`'Content-Length': text.length,
`
2143
2153
`}
`
2144
2154
`});
`
2145
``
`-
safe.Object_defineProperty(response, 'url', {
`
2146
``
`-
value: details.url
`
2147
``
`-
});
`
2148
``
`-
if ( responseType !== '' ) {
`
2149
``
`-
safe.Object_defineProperty(response, 'type', {
`
2150
``
`-
value: responseType
`
2151
``
`-
});
`
2152
``
`-
}
`
``
2155
`+
const props = Object.assign(
`
``
2156
`+
{ url: { value: details.url } },
`
``
2157
`+
responseProps
`
``
2158
`+
);
`
``
2159
`+
safe.Object_defineProperties(response, props);
`
2153
2160
`return response;
`
2154
2161
`});
`
2155
2162
`}
`