Skip to content

Commit

Permalink
allow to modify the body response
Browse files Browse the repository at this point in the history
  • Loading branch information
vpalmisano committed Sep 18, 2024
1 parent d455268 commit d3c99af
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
10 changes: 7 additions & 3 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,13 @@ blocked.`,
arg: 'extra-headers',
},
responseModifiers: {
doc: `A dictionary of content replacements keyed by the url in JSON5 format (e.g. \
\`{ "https://url.com/*": [{ search: "searchString": replace: "anotherString" }] }\`).\
The search string should be a valid regular expression.`,
doc: `A dictionary of content replacements keyed by the url in JSON5 format.
Examples:
- replace strings using a regular expression:
\`{ "https://url.com/*": [{ search: "searchString": replace: "anotherString" }] }\`
- completely replace the content:
\`{ "https://url.com/file.js": [{ file: "path/to/newFile.js" }] }\`
`,
format: String,
nullable: true,
default: '',
Expand Down
60 changes: 45 additions & 15 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,12 @@ export class Session extends EventEmitter {
private readonly extraHeaders?: Record<string, Record<string, string>>
private readonly responseModifiers: Record<
string,
{ search: RegExp; replace: string }[]
{
search?: RegExp
replace?: string
file?: string
headers?: Record<string, string>
}[]
> = {}
private readonly extraCSS: string
private readonly cookies?: Record<string, string>
Expand Down Expand Up @@ -491,18 +496,30 @@ export class Session extends EventEmitter {
try {
const parsed = JSON5.parse(responseModifiers) as Record<
string,
{ search: string; replace: string }[]
{
search?: string
replace?: string
file?: string
headers?: Record<string, string>
}[]
>
Object.entries(parsed).forEach(([url, replacements]) => {
if (!Array.isArray(replacements)) {
throw new Error(
`responseModifiers replacements should be an array of { search, replace, body, headers } objects: ${replacements}`,
)
}
this.responseModifiers[url] = replacements.map(
({ search, replace }) => ({
search: new RegExp(search, 'g'),
({ search, replace, file, headers }) => ({
search: search ? new RegExp(search, 'g') : undefined,
replace,
file,
headers,
}),
)
})
} catch (err) {
log.error(
throw new Error(
`error parsing responseModifiers "${responseModifiers}": ${
(err as Error).stack
}`,
Expand Down Expand Up @@ -549,6 +566,9 @@ export class Session extends EventEmitter {
`--unsafely-treat-insecure-origin-as-secure=http://${
new URL(this.url || 'http://localhost').host
}`,
'--disable-web-security',
'--disable-features=IsolateOrigins',
'--disable-site-isolation-trials',
'--use-fake-ui-for-media-stream',
'--enable-usermedia-screen-capturing',
'--allow-http-screen-capture',
Expand Down Expand Up @@ -1094,17 +1114,27 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
Object.entries(this.responseModifiers).forEach(([url, replacements]) => {
interceptions.push({
urlPattern: url,
modifyResponse: ({ event, body }) => {
if (body) {
log.debug(
`using responseModifiers in: ${event.request.url}`,
replacements.map(
({ search, replace }) => `${search.toString()} => ${replace}`,
),
)
replacements.forEach(({ search, replace }) => {
modifyResponse: async ({ event, body }) => {
for (const { search, replace, file, headers } of replacements) {
if (search && replace) {
log.debug(
`using responseModifiers in: ${event.request.url}: ${search.toString()} => ${replace}`,
)
body = body?.replace(search, replace)
})
} else if (file) {
log.log(
`using responseModifiers in: ${event.request.url}: ${file}`,
)
body = await fs.promises.readFile(file, 'utf8')
}
if (headers) {
for (const [name, value] of Object.entries(headers)) {
event.responseHeaders?.push({
name,
value,
})
}
}
}
return { body }
},
Expand Down

0 comments on commit d3c99af

Please sign in to comment.