Skip to content

Commit 83762e0

Browse files
authored
fix(core): Handle gzip and deflate compressed request payloads (#7461)
NODE-870
1 parent ef58a23 commit 83762e0

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

packages/cli/src/middlewares/bodyParser.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import getRawBody from 'raw-body';
2+
import { type Readable } from 'stream';
3+
import { createGunzip, createInflate } from 'zlib';
24
import type { Request, RequestHandler } from 'express';
35
import { parse as parseQueryString } from 'querystring';
46
import { Parser as XmlParser } from 'xml2js';
@@ -20,8 +22,21 @@ export const rawBodyReader: RequestHandler = async (req, res, next) => {
2022

2123
req.readRawBody = async () => {
2224
if (!req.rawBody) {
23-
req.rawBody = await getRawBody(req, {
24-
length: req.headers['content-length'],
25+
let stream: Readable = req;
26+
let contentLength: string | undefined;
27+
const contentEncoding = req.headers['content-encoding'];
28+
switch (contentEncoding) {
29+
case 'gzip':
30+
stream = req.pipe(createGunzip());
31+
break;
32+
case 'deflate':
33+
stream = req.pipe(createInflate());
34+
break;
35+
default:
36+
contentLength = req.headers['content-length'];
37+
}
38+
req.rawBody = await getRawBody(stream, {
39+
length: contentLength,
2540
limit: `${String(payloadSizeMax)}mb`,
2641
});
2742
req._body = true;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { createServer } from 'http';
2+
import { gzipSync, deflateSync } from 'zlib';
3+
import type { Request, Response } from 'express';
4+
import request from 'supertest';
5+
import { rawBodyReader, bodyParser } from '@/middlewares/bodyParser';
6+
7+
describe('bodyParser', () => {
8+
const server = createServer((req: Request, res: Response) => {
9+
rawBodyReader(req, res, async () => {
10+
bodyParser(req, res, () => res.end(JSON.stringify(req.body)));
11+
});
12+
});
13+
14+
it('should handle uncompressed data', async () => {
15+
const response = await request(server).post('/').send({ hello: 'world' }).expect(200);
16+
expect(response.text).toEqual('{"hello":"world"}');
17+
});
18+
19+
it('should handle gzip data', async () => {
20+
const response = await request(server)
21+
.post('/')
22+
.set('content-encoding', 'gzip')
23+
// @ts-ignore
24+
.serialize((d) => gzipSync(JSON.stringify(d)))
25+
.send({ hello: 'world' })
26+
.expect(200);
27+
expect(response.text).toEqual('{"hello":"world"}');
28+
});
29+
30+
it('should handle deflate data', async () => {
31+
const response = await request(server)
32+
.post('/')
33+
.set('content-encoding', 'deflate')
34+
// @ts-ignore
35+
.serialize((d) => deflateSync(JSON.stringify(d)))
36+
.send({ hello: 'world' })
37+
.expect(200);
38+
expect(response.text).toEqual('{"hello":"world"}');
39+
});
40+
});

0 commit comments

Comments
 (0)