Skip to content

Commit

Permalink
Merge branch 'master' into fix/AG-21081
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamWr committed Jun 29, 2023
2 parents 9395fa5 + c6b7eda commit 18cfaca
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- ability to use flags in RegExp [#303](https://github.com/AdguardTeam/Scriptlets/issues/303)

### Fixed

- error throwing in `prevent-fetch` and `prevent-xhr` scriptlets when a request is blocked
[#334](https://github.com/AdguardTeam/Scriptlets/issues/334)

## <a name="v1.9.37"></a> [v1.9.37] - 2023-06-06

### Added
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adguard/scriptlets",
"version": "1.9.41",
"version": "1.9.42",
"description": "AdGuard's JavaScript library of Scriptlets and Redirect resources",
"scripts": {
"build": "babel-node -x .js,.ts scripts/build.js",
Expand Down
29 changes: 21 additions & 8 deletions src/scriptlets/prevent-fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
objectToString,
matchRequestProps,
logMessage,
noopPromiseResolve,
modifyResponse,
// following helpers should be imported and injected
// because they are used by helpers above
Expand Down Expand Up @@ -156,14 +157,25 @@ export function preventFetch(source, propsToMatch, responseBody = 'emptyObj', re

if (shouldPrevent) {
hit(source);
const origResponse = await Reflect.apply(target, thisArg, args);
return modifyResponse(
origResponse,
{
body: strResponseBody,
type: responseType,
},
);
try {
const origResponse = await Reflect.apply(target, thisArg, args);
// In the case of apps, the blocked request has status 500
// and no error is thrown, so it's necessary to check response.ok
// https://github.com/AdguardTeam/Scriptlets/issues/334
if (!origResponse.ok) {
return noopPromiseResolve(strResponseBody, fetchData.url, responseType);
}
return modifyResponse(
origResponse,
{
body: strResponseBody,
type: responseType,
},
);
} catch (ex) {
// https://github.com/AdguardTeam/Scriptlets/issues/334
return noopPromiseResolve(strResponseBody, fetchData.url, responseType);
}
}

return Reflect.apply(target, thisArg, args);
Expand All @@ -190,6 +202,7 @@ preventFetch.injections = [
objectToString,
matchRequestProps,
logMessage,
noopPromiseResolve,
modifyResponse,
toRegExp,
isValidStrPattern,
Expand Down
6 changes: 3 additions & 3 deletions src/scriptlets/prevent-xhr.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,19 @@ export function preventXHR(source, propsToMatch, customResponseText) {
readyState,
responseURL,
responseXML,
status,
statusText,
} = forgedRequest;

// Mock response object
Object.defineProperties(thisArg, {
// original values
readyState: { value: readyState, writable: false },
status: { value: status, writable: false },
statusText: { value: statusText, writable: false },
responseURL: { value: responseURL, writable: false },
// If the request is blocked, responseURL is an empty string
responseURL: { value: responseURL || xhrData.url, writable: false },
responseXML: { value: responseXML, writable: false },
// modified values
status: { value: 200, writable: false },
response: { value: modifiedResponse, writable: false },
responseText: { value: modifiedResponseText, writable: false },
});
Expand Down
22 changes: 22 additions & 0 deletions tests/scriptlets/prevent-fetch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,28 @@ if (!isSupported) {
done();
});

test('prevent not existing fetch call', async (assert) => {
// blocked_request.json doesn't exist,
// it's required for test for blocked requests
const BLOCKED_REQUEST = `${FETCH_OBJECTS_PATH}/blocked_request.json`;
const inputRequest = new Request(BLOCKED_REQUEST);

runScriptlet(name, ['blocked_request']);
const done = assert.async(1);

const response = await fetch(inputRequest);
const parsedData = await response.json();

if (!response.ok) {
assert.strictEqual(response.ok, true, 'Request blocked');
done();
}
assert.ok(response.url.includes('/blocked_request.json'), 'Response URL is mocked');
assert.ok(isEmptyObject(parsedData), 'Response is mocked');
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
done();
});

test('simple fetch - match single pair prop', async (assert) => {
const INPUT_JSON_PATH = `${FETCH_OBJECTS_PATH}/test03.json`;
const options = {
Expand Down
26 changes: 26 additions & 0 deletions tests/scriptlets/prevent-xhr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,32 @@ if (isSupported) {
xhr.send();
});

test('Args matched, prevent blocked request', async (assert) => {
// blocked_request.json doesn't exist,
// it's required for test for blocked requests
const METHOD = 'GET';
const URL = `${FETCH_OBJECTS_PATH}/blocked_request.json`;
const MATCH_DATA = [`blocked_request method:${METHOD}`];

runScriptlet(name, MATCH_DATA);

const done = assert.async();

const reqListener = (e) => {
assert.strictEqual(e.target.status, 200, 'Status mocked');
assert.ok(e.target.responseURL.includes('/blocked_request.json'), 'Origianl URL mocked');
assert.strictEqual(e.target.readyState, 4, 'Response done');
assert.strictEqual(e.target.response, '', 'Response data mocked');
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
done();
};

const xhr = new XMLHttpRequest();
xhr.open(METHOD, URL);
xhr.addEventListener('load', reqListener);
xhr.send();
});

test('Args, match, listeners after .send work', async (assert) => {
const METHOD = 'GET';
const URL = `${FETCH_OBJECTS_PATH}/test01.json`;
Expand Down

0 comments on commit 18cfaca

Please sign in to comment.