Skip to content

Commit 3e8429f

Browse files
committed
AG-31638 Improve 'prevent-fetch' — add ability to set random response content. #416
Squashed commit of the following: commit afcdf8d Merge: b61d76f bd11dba Author: Adam Wróblewski <[email protected]> Date: Tue Apr 22 08:07:44 2025 +0200 Merge branch 'master' into feature/AG-31638 commit b61d76f Merge: 23139ca 61825cc Author: Slava Leleka <[email protected]> Date: Thu Apr 17 13:57:52 2025 -0400 merge the parent branch into the current branch, resolve conflicts commit 23139ca Author: Adam Wróblewski <[email protected]> Date: Wed Apr 16 12:47:33 2025 +0200 Improve 'prevent-fetch' — add ability to set random response content
1 parent bd11dba commit 3e8429f

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
1414

1515
### Added
1616

17+
- Ability to set random response content in `prevent-fetch` scriptlet [#416].
1718
- Ability to choose CSS injection method in `inject-css-in-shadow-dom` scriptlet [#477].
1819
- TypeScript types for CoreLibs provided [`ContentScriptApi`](./README.md#scriptlets-api--content-script-api).
1920
- Trusted Types API utility — [`PolicyApi`](./README.md#scriptlets-api--content-script-api--policy-api).
@@ -24,6 +25,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
2425

2526
[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v2.1.7...HEAD
2627
[#392]: https://github.com/AdguardTeam/Scriptlets/issues/392
28+
[#416]: https://github.com/AdguardTeam/Scriptlets/issues/416
2729
[#477]: https://github.com/AdguardTeam/Scriptlets/issues/477
2830

2931
## [v2.1.7] - 2025-04-03

src/helpers/noop-utils.ts

+3
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ export const noopPromiseResolve = (
113113
}
114114

115115
const response = new Response(responseBody, {
116+
headers: {
117+
'Content-Length': `${responseBody.length}`,
118+
},
116119
status: 200,
117120
statusText: 'OK',
118121
});

src/scriptlets/prevent-fetch.js

+24
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import {
1515
parseMatchProps,
1616
isValidParsedData,
1717
getMatchPropsData,
18+
generateRandomResponse,
19+
nativeIsFinite,
20+
nativeIsNaN,
21+
getNumberFromString,
22+
getRandomIntInclusive,
23+
getRandomStrByLength,
1824
} from '../helpers';
1925

2026
/* eslint-disable max-len */
@@ -46,6 +52,10 @@ import {
4652
* - `emptyObj` — empty object
4753
* - `emptyArr` — empty array
4854
* - `emptyStr` — empty string
55+
* - `true` — random alphanumeric string of 10 symbols
56+
* - colon-separated pair `name:value` string value to customize `responseBody` where
57+
* - `name` — only `length` supported for now
58+
* - `value` — range on numbers, for example `100-300`, limited to 500000 characters
4959
* - `responseType` — optional, string for defining response type,
5060
* original response type is used if not specified. Possible values:
5161
* - `basic`
@@ -97,6 +107,12 @@ import {
97107
*
98108
* ! Specify response body for all fetch calls
99109
* example.org#%#//scriptlet('prevent-fetch', '', 'emptyArr')
110+
*
111+
* ! Specify response body to random alphanumeric string of 10 symbols for all fetch calls
112+
* example.org#%#//scriptlet('prevent-fetch', '', 'true')
113+
*
114+
* ! Specify response body to random alphanumeric string with specific range for all fetch calls
115+
* example.org#%#//scriptlet('prevent-fetch', '', 'length:100-300')
100116
* ```
101117
*
102118
* 1. Prevent all fetch calls and specify response type value
@@ -128,6 +144,8 @@ export function preventFetch(source, propsToMatch, responseBody = 'emptyObj', re
128144
strResponseBody = '[]';
129145
} else if (responseBody === 'emptyStr') {
130146
strResponseBody = '';
147+
} else if (responseBody === 'true' || responseBody.match(/^length:\d+-\d+$/)) {
148+
strResponseBody = generateRandomResponse(responseBody);
131149
} else {
132150
logMessage(source, `Invalid responseBody parameter: '${responseBody}'`);
133151
return;
@@ -249,4 +267,10 @@ preventFetch.injections = [
249267
parseMatchProps,
250268
isValidParsedData,
251269
getMatchPropsData,
270+
generateRandomResponse,
271+
nativeIsFinite,
272+
nativeIsNaN,
273+
getNumberFromString,
274+
getRandomIntInclusive,
275+
getRandomStrByLength,
252276
];

tests/scriptlets/prevent-fetch.test.js

+33
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,39 @@ if (!isSupported) {
294294
done();
295295
});
296296

297+
test('simple fetch - returns random string of 10 symbols', async (assert) => {
298+
const INPUT_JSON_PATH_1 = `${FETCH_OBJECTS_PATH}/test01.json`;
299+
const inputRequest1 = new Request(INPUT_JSON_PATH_1);
300+
301+
runScriptlet(name, ['test01', 'true']);
302+
const done = assert.async();
303+
304+
const response = await fetch(inputRequest1);
305+
const parsedData = await response.text();
306+
307+
assert.strictEqual(parsedData.length, 10, 'Response length is correct');
308+
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
309+
done();
310+
});
311+
312+
test('simple fetch - returns random string with specific range', async (assert) => {
313+
// blocked_request.json doesn't exist,
314+
// it's required for test for blocked requests
315+
const BLOCKED_REQUEST = `${FETCH_OBJECTS_PATH}/blocked_request.json`;
316+
317+
runScriptlet(name, ['blocked_request', 'length:50-100']);
318+
const done = assert.async();
319+
320+
const response = await fetch(BLOCKED_REQUEST);
321+
const parsedData = await response.text();
322+
const headerLength = Number(response.headers.get('Content-Length'));
323+
324+
assert.ok(parsedData.length >= 50 && parsedData.length <= 100, 'Response length is correct');
325+
assert.strictEqual(headerLength, parsedData.length, 'Header length matches response length');
326+
assert.strictEqual(window.hit, 'FIRED', 'hit function fired');
327+
done();
328+
});
329+
297330
test('simple fetch - valid response type', async (assert) => {
298331
const OPAQUE_RESPONSE_TYPE = 'opaque';
299332
const INPUT_JSON_PATH = `${FETCH_OBJECTS_PATH}/test01.json`;

0 commit comments

Comments
 (0)