From 34de0811d9a6980c69f01be9d03251c2f2496b4b Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 26 Mar 2024 19:26:55 +1100 Subject: [PATCH] fix(runtime-handler): don't check for exact Content-Type matches (#392) * fix(runtime-handler): don't check for exact Content-Type matches Content-Type headers may have the media type followed by a semicolon, followed by some parameters, for example "charset=UTF-8". This fix ensures that only the start of the Content-Type header matches application/json when stringifying the body to JSON. Fixes #391 * chore: add changeset --------- Co-authored-by: Victor Ayogu --- .changeset/friendly-turtles-pretend.md | 5 +++++ .../dev-runtime/internal/response.test.ts | 18 ++++++++++++++++++ .../src/dev-runtime/internal/response.ts | 15 ++++++++++----- 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 .changeset/friendly-turtles-pretend.md diff --git a/.changeset/friendly-turtles-pretend.md b/.changeset/friendly-turtles-pretend.md new file mode 100644 index 00000000..03d29d63 --- /dev/null +++ b/.changeset/friendly-turtles-pretend.md @@ -0,0 +1,5 @@ +--- +'@twilio/runtime-handler': patch +--- + +Don't check for exact Content-Type matches diff --git a/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts b/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts index 8a54e45a..aee87042 100644 --- a/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts +++ b/packages/runtime-handler/__tests__/dev-runtime/internal/response.test.ts @@ -292,3 +292,21 @@ test('serializes a response with content type set to application/json', () => { 'Set-Cookie': [], }); }); + +test('serializes a response with content type set to application/json with a charset', () => { + const response = new Response(); + response.setBody({ url: 'https://dkundel.com' }); + response.setStatusCode(200); + response.appendHeader('Content-Type', 'application/json; charset=UTF-8'); + + const serialized = response.serialize(); + + expect(serialized.body).toEqual( + JSON.stringify({ url: 'https://dkundel.com' }) + ); + expect(serialized.statusCode).toEqual(200); + expect(serialized.headers).toEqual({ + 'Content-Type': 'application/json; charset=UTF-8', + 'Set-Cookie': [], + }); +}); diff --git a/packages/runtime-handler/src/dev-runtime/internal/response.ts b/packages/runtime-handler/src/dev-runtime/internal/response.ts index 20ec8285..5f418883 100644 --- a/packages/runtime-handler/src/dev-runtime/internal/response.ts +++ b/packages/runtime-handler/src/dev-runtime/internal/response.ts @@ -79,7 +79,7 @@ export class Response implements TwilioResponse { this.headers[COOKIE_HEADER] = newHeaderValue; } } else { - this.headers[COOKIE_HEADER] = Array.isArray(value) ? value: [value]; + this.headers[COOKIE_HEADER] = Array.isArray(value) ? value : [value]; } } else { const existingValue = this.headers[key]; @@ -133,12 +133,17 @@ export class Response implements TwilioResponse { } serialize() { + const contentType = this.headers['Content-Type']; + let body = this.body; + if ( + typeof contentType === 'string' && + contentType.startsWith('application/json') + ) { + body = JSON.stringify(body); + } return { statusCode: this.statusCode, - body: - this.headers['Content-Type'] === 'application/json' - ? JSON.stringify(this.body) - : this.body, + body: body, headers: this.headers, }; }