diff --git a/src/handlers/fix-request-body.ts b/src/handlers/fix-request-body.ts index cc47e68f..fc9019c7 100644 --- a/src/handlers/fix-request-body.ts +++ b/src/handlers/fix-request-body.ts @@ -1,5 +1,6 @@ import type * as http from 'node:http'; import * as querystring from 'node:querystring'; +import * as zlib from 'node:zlib'; export type BodyParserLikeRequest = http.IncomingMessage & { body?: any }; @@ -28,8 +29,23 @@ export function fixRequestBody { - proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); - proxyReq.write(bodyData); + let proxyData: string | Buffer = bodyData; + + const contentEncoding = String(proxyReq.getHeader('Content-Encoding')).toLowerCase(); + switch (contentEncoding) { + case 'br': + proxyData = zlib.brotliCompressSync(proxyData); + break; + case 'deflate': + proxyData = zlib.deflateSync(proxyData); + break; + case 'gzip': + proxyData = zlib.gzipSync(proxyData); + break; + } + + proxyReq.setHeader('Content-Length', Buffer.byteLength(proxyData)); + proxyReq.write(proxyData); }; // Use if-elseif to prevent multiple writeBody/setHeader calls: diff --git a/test/unit/fix-request-body.spec.ts b/test/unit/fix-request-body.spec.ts index 4615c67c..254aa839 100644 --- a/test/unit/fix-request-body.spec.ts +++ b/test/unit/fix-request-body.spec.ts @@ -1,6 +1,7 @@ import { ClientRequest, IncomingMessage, ServerResponse } from 'node:http'; import { Socket } from 'node:net'; import * as querystring from 'node:querystring'; +import * as zlib from 'node:zlib'; import { BodyParserLikeRequest, fixRequestBody } from '../../src/handlers/fix-request-body'; @@ -213,4 +214,20 @@ describe('fixRequestBody', () => { expect(proxyRequest.write).toHaveBeenCalledTimes(0); expect(proxyRequest.destroy).toHaveBeenCalledTimes(0); }); + + it('should re-encode body when the source was encoded', () => { + const proxyRequest = fakeProxyRequest(); + proxyRequest.setHeader('content-type', 'application/json; charset=utf-8'); + proxyRequest.setHeader('content-encoding', 'gzip'); + + jest.spyOn(proxyRequest, 'setHeader'); + jest.spyOn(proxyRequest, 'write'); + + const data = { someField: 'some value' }; + fixRequestBody(proxyRequest, createRequestWithBody(data)); + + const expectedBody = zlib.gzipSync(JSON.stringify(data)); + expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length); + expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody); + }); });