From b788613c5005092b2608558e5c8af6c90ce3cdd6 Mon Sep 17 00:00:00 2001 From: Tim Dawborn Date: Wed, 9 Mar 2022 13:38:34 +1100 Subject: [PATCH 1/6] [AUTH-1236] Prevent conditional requests from being made during tape recording, so that conditional responses are not returned during replay. --- src/cli.ts | 8 ++++++++ src/server.ts | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/cli.ts b/src/cli.ts index 0046ee92..73c47214 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -24,6 +24,11 @@ async function main(argv: string[]) { "Request headers to redact", commaSeparatedList ) + .option( + "--prevent-conditional-requests ", + "When running in record mode, remove `If-*` headers from outgoing requests in an attempt to prevent the suite of conditional responses being returned (304).", + "false" + ) .parse(argv); const initialMode: string = (program.mode || "").toLowerCase(); @@ -32,6 +37,8 @@ async function main(argv: string[]) { const host: string = program.host; const port = parseInt(program.port, 10); const redactHeaders: string[] = program.redactHeaders; + const preventConditionalRequests: boolean = + program.preventConditionalRequests === "true"; switch (initialMode) { case "record": @@ -72,6 +79,7 @@ async function main(argv: string[]) { defaultTapeName, enableLogging: true, redactHeaders, + preventConditionalRequests, }); await server.start(port); console.log(chalk.green(`Proxying in ${initialMode} mode on port ${port}.`)); diff --git a/src/server.ts b/src/server.ts index 8c68216a..eb92c576 100644 --- a/src/server.ts +++ b/src/server.ts @@ -23,6 +23,7 @@ export class RecordReplayServer { private loggingEnabled: boolean; private defaultTape: string; private replayedTapes: Set = new Set(); + private preventConditionalRequests?: boolean; constructor(options: { initialMode: Mode; @@ -32,6 +33,7 @@ export class RecordReplayServer { timeout?: number; enableLogging?: boolean; redactHeaders?: string[]; + preventConditionalRequests?: boolean; }) { this.currentTapeRecords = []; this.mode = options.initialMode; @@ -41,6 +43,7 @@ export class RecordReplayServer { const redactHeaders = options.redactHeaders || []; this.persistence = new Persistence(options.tapeDir, redactHeaders); this.defaultTape = options.defaultTapeName; + this.preventConditionalRequests = options.preventConditionalRequests; this.loadTape(this.defaultTape); this.server = http.createServer(async (req, res) => { @@ -57,6 +60,14 @@ export class RecordReplayServer { return; } + if ( + this.preventConditionalRequests && + (req.method === "GET" || req.method === "HEAD") + ) { + delete req.headers["If-Modified-Since"]; + delete req.headers["If-None-Match"]; + } + try { const request: Request = { method: req.method, From 3f2ad0df12e4da0cdceadef0c9eeb1c8cd7f5058 Mon Sep 17 00:00:00 2001 From: Tim Dawborn Date: Wed, 9 Mar 2022 14:14:01 +1100 Subject: [PATCH 2/6] Debugging. --- src/server.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server.ts b/src/server.ts index eb92c576..9350d2f2 100644 --- a/src/server.ts +++ b/src/server.ts @@ -66,6 +66,7 @@ export class RecordReplayServer { ) { delete req.headers["If-Modified-Since"]; delete req.headers["If-None-Match"]; + console.log(`Attempted to delete headers. ${req.method} ${JSON.stringify(req.headers)}`); } try { From b36fe1b452684c27a9e929aa45367ece866bab78 Mon Sep 17 00:00:00 2001 From: Tim Dawborn Date: Wed, 9 Mar 2022 14:34:18 +1100 Subject: [PATCH 3/6] Lowercase headers. --- src/server.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/server.ts b/src/server.ts index 9350d2f2..434e6ff4 100644 --- a/src/server.ts +++ b/src/server.ts @@ -64,8 +64,9 @@ export class RecordReplayServer { this.preventConditionalRequests && (req.method === "GET" || req.method === "HEAD") ) { - delete req.headers["If-Modified-Since"]; - delete req.headers["If-None-Match"]; + // Headers are always coming in as lowercase. + delete req.headers["if-modified-since"]; + delete req.headers["if-none-match"]; console.log(`Attempted to delete headers. ${req.method} ${JSON.stringify(req.headers)}`); } From 60aee12f4740f764939eb5410f1c7e6fca817b25 Mon Sep 17 00:00:00 2001 From: Tim Dawborn Date: Wed, 9 Mar 2022 14:46:44 +1100 Subject: [PATCH 4/6] Remove debugging. --- src/server.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server.ts b/src/server.ts index 434e6ff4..1875d905 100644 --- a/src/server.ts +++ b/src/server.ts @@ -67,7 +67,6 @@ export class RecordReplayServer { // Headers are always coming in as lowercase. delete req.headers["if-modified-since"]; delete req.headers["if-none-match"]; - console.log(`Attempted to delete headers. ${req.method} ${JSON.stringify(req.headers)}`); } try { From a5fbaf1658fa1d5ce451a21dfa799a5e2b95d188 Mon Sep 17 00:00:00 2001 From: Tim Dawborn Date: Thu, 10 Mar 2022 11:48:32 +1100 Subject: [PATCH 5/6] Set default to be true. --- src/cli.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index 73c47214..71850794 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -27,7 +27,7 @@ async function main(argv: string[]) { .option( "--prevent-conditional-requests ", "When running in record mode, remove `If-*` headers from outgoing requests in an attempt to prevent the suite of conditional responses being returned (304).", - "false" + "true" ) .parse(argv); @@ -62,6 +62,12 @@ async function main(argv: string[]) { ); } + if (initialMode === "record" && preventConditionalRequests) { + console.info( + "The prevent conditional requests flag is enabled in record mode. All received `If-*` headers will not be forwarded on upstream and will not be recorded in tapes." + ); + } + // Expect a host unless we're in replay mode. if (initialMode !== "replay") { if (!host) { From 9243023f89a456a22be82c2857d12e5bf2a7e425 Mon Sep 17 00:00:00 2001 From: Tim Dawborn Date: Sat, 12 Mar 2022 10:22:34 +1100 Subject: [PATCH 6/6] PR feedback. --- src/cli.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 71850794..f913c0f3 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -25,9 +25,8 @@ async function main(argv: string[]) { commaSeparatedList ) .option( - "--prevent-conditional-requests ", - "When running in record mode, remove `If-*` headers from outgoing requests in an attempt to prevent the suite of conditional responses being returned (304).", - "true" + "--no-drop-conditional-request-headers", + "When running in record mode, by default, `If-*` headers from outgoing requests are dropped in an attempt to prevent the suite of conditional responses being returned (e.g. 304). Supplying this flag disables this default behaviour" ) .parse(argv); @@ -37,8 +36,7 @@ async function main(argv: string[]) { const host: string = program.host; const port = parseInt(program.port, 10); const redactHeaders: string[] = program.redactHeaders; - const preventConditionalRequests: boolean = - program.preventConditionalRequests === "true"; + const preventConditionalRequests: boolean = !!program.dropConditionalRequestHeaders; switch (initialMode) { case "record": @@ -62,7 +60,7 @@ async function main(argv: string[]) { ); } - if (initialMode === "record" && preventConditionalRequests) { + if (preventConditionalRequests && initialMode === "record") { console.info( "The prevent conditional requests flag is enabled in record mode. All received `If-*` headers will not be forwarded on upstream and will not be recorded in tapes." );