diff --git a/src/mockServiceWorker.js b/src/mockServiceWorker.js index 699f43aef..536b15178 100644 --- a/src/mockServiceWorker.js +++ b/src/mockServiceWorker.js @@ -147,7 +147,11 @@ async function handleRequest(event, requestId) { if (client && activeClientIds.has(client.id)) { ;(async function () { const clonedResponse = response.clone() - sendToClient(client, { + const body = + clonedResponse.body === null + ? undefined + : await clonedResponse.arrayBuffer() + const message = { type: 'RESPONSE', payload: { requestId, @@ -155,12 +159,12 @@ async function handleRequest(event, requestId) { ok: clonedResponse.ok, status: clonedResponse.status, statusText: clonedResponse.statusText, - body: - clonedResponse.body === null ? null : await clonedResponse.text(), + body, headers: Object.fromEntries(clonedResponse.headers.entries()), redirected: clonedResponse.redirected, }, - }) + } + sendToClient(client, message, body && [body]) })() } @@ -200,7 +204,7 @@ async function getResponse(event, client, requestId) { function passthrough() { // Clone the request because it might've been already used - // (i.e. its body has been read and sent to the cilent). + // (i.e. its body has been read and sent to the client). const headers = Object.fromEntries(clonedRequest.headers.entries()) // Remove MSW-specific request headers so the bypassed requests @@ -239,7 +243,7 @@ async function getResponse(event, client, requestId) { ) // Notify the client that a request has been intercepted. - const clientMessage = await sendToClient(client, { + const message = { type: 'REQUEST', payload: { id: requestId, @@ -254,11 +258,14 @@ async function getResponse(event, client, requestId) { redirect: request.redirect, referrer: request.referrer, referrerPolicy: request.referrerPolicy, - body: await request.text(), + body: await request.arrayBuffer(), bodyUsed: request.bodyUsed, keepalive: request.keepalive, }, - }) + } + const clientMessage = await sendToClient(client, message, [ + message.payload.body, + ]) switch (clientMessage.type) { case 'MOCK_RESPONSE': { @@ -304,7 +311,7 @@ This exception has been gracefully handled as a 500 response, however, it's stro return passthrough() } -function sendToClient(client, message) { +function sendToClient(client, message, transfer) { return new Promise((resolve, reject) => { const channel = new MessageChannel() @@ -316,7 +323,7 @@ function sendToClient(client, message) { resolve(event.data) } - client.postMessage(message, [channel.port2]) + client.postMessage(message, [channel.port2].concat(transfer || [])) }) } diff --git a/src/setupWorker/glossary.ts b/src/setupWorker/glossary.ts index 417f1dbed..419b2e7f5 100644 --- a/src/setupWorker/glossary.ts +++ b/src/setupWorker/glossary.ts @@ -38,9 +38,9 @@ export interface ServiceWorkerIncomingRequest extends RequestWithoutMethods { id: string /** - * Text response body. + * Response body. */ - body?: string + body?: ArrayBuffer } export type ServiceWorkerIncomingResponse = Pick< diff --git a/src/utils/request/parseWorkerRequest.ts b/src/utils/request/parseWorkerRequest.ts index cc8b45fd7..71b4a1658 100644 --- a/src/utils/request/parseWorkerRequest.ts +++ b/src/utils/request/parseWorkerRequest.ts @@ -1,4 +1,3 @@ -import { encodeBuffer } from '@mswjs/interceptors' import { Headers } from 'headers-polyfill' import { ServiceWorkerIncomingRequest } from '../../setupWorker/glossary' import { MockedRequest } from './MockedRequest' @@ -13,9 +12,5 @@ export function parseWorkerRequest( const url = new URL(rawRequest.url) const headers = new Headers(rawRequest.headers) - return new MockedRequest(url, { - ...rawRequest, - body: encodeBuffer(rawRequest.body || ''), - headers, - }) + return new MockedRequest(url, { ...rawRequest, headers }) } diff --git a/src/utils/request/pruneGetRequestBody.test.ts b/src/utils/request/pruneGetRequestBody.test.ts deleted file mode 100644 index 1c08e25a4..000000000 --- a/src/utils/request/pruneGetRequestBody.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @jest-environment jsdom - */ -import { pruneGetRequestBody } from './pruneGetRequestBody' - -test('sets empty GET request body to undefined', () => { - const body = pruneGetRequestBody({ - method: 'GET', - body: '', - }) - - expect(body).toBeUndefined() -}) - -test('preserves non-empty GET request body', () => { - const body = pruneGetRequestBody({ - method: 'GET', - body: 'text-body', - }) - - expect(body).toBe('text-body') -}) - -test('ignores requests of the other method than GET', () => { - expect( - pruneGetRequestBody({ - method: 'HEAD', - body: JSON.stringify({ a: 1 }), - }), - ).toBe(JSON.stringify({ a: 1 })) - - expect( - pruneGetRequestBody({ - method: 'POST', - body: 'text-body', - }), - ).toBe('text-body') -}) diff --git a/src/utils/request/pruneGetRequestBody.ts b/src/utils/request/pruneGetRequestBody.ts deleted file mode 100644 index d6f1e1ce7..000000000 --- a/src/utils/request/pruneGetRequestBody.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ServiceWorkerIncomingRequest } from '../../setupWorker/glossary' -import { isStringEqual } from '../internal/isStringEqual' - -type Input = Pick - -/** - * Ensures that an empty GET request body is always represented as `undefined`. - */ -export function pruneGetRequestBody( - request: Input, -): ServiceWorkerIncomingRequest['body'] { - if ( - request.method && - isStringEqual(request.method, 'GET') && - request.body === '' - ) { - return undefined - } - - return request.body -}