Skip to content

Commit 0209760

Browse files
authored
fix(fixRequestBody): prevent multiple .write() calls (#1089)
1 parent fd0f568 commit 0209760

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

src/handlers/fix-request-body.ts

+10-8
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,23 @@ export function fixRequestBody<TReq = http.IncomingMessage>(
1717
}
1818

1919
const contentType = proxyReq.getHeader('Content-Type') as string;
20+
21+
if (!contentType) {
22+
return;
23+
}
24+
2025
const writeBody = (bodyData: string) => {
21-
// deepcode ignore ContentLengthInCode: bodyParser fix
2226
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
2327
proxyReq.write(bodyData);
2428
};
2529

26-
if (contentType && (contentType.includes('application/json') || contentType.includes('+json'))) {
30+
// Use if-elseif to prevent multiple writeBody/setHeader calls:
31+
// Error: "Cannot set headers after they are sent to the client"
32+
if (contentType.includes('application/json') || contentType.includes('+json')) {
2733
writeBody(JSON.stringify(requestBody));
28-
}
29-
30-
if (contentType && contentType.includes('application/x-www-form-urlencoded')) {
34+
} else if (contentType.includes('application/x-www-form-urlencoded')) {
3135
writeBody(querystring.stringify(requestBody));
32-
}
33-
34-
if (contentType && contentType.includes('multipart/form-data')) {
36+
} else if (contentType.includes('multipart/form-data')) {
3537
writeBody(handlerFormDataBodyData(contentType, requestBody));
3638
}
3739
}

test/unit/fix-request-body.spec.ts

+15
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,19 @@ describe('fixRequestBody', () => {
154154
expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length);
155155
expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody);
156156
});
157+
158+
it('should parse json and call write() once with incorrect content-type application/x-www-form-urlencoded+json', () => {
159+
const proxyRequest = fakeProxyRequest();
160+
proxyRequest.setHeader('content-type', 'application/x-www-form-urlencoded+json');
161+
162+
jest.spyOn(proxyRequest, 'setHeader');
163+
jest.spyOn(proxyRequest, 'write');
164+
165+
fixRequestBody(proxyRequest, createRequestWithBody({ someField: 'some value' }));
166+
167+
const expectedBody = JSON.stringify({ someField: 'some value' });
168+
expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length);
169+
expect(proxyRequest.write).toHaveBeenCalledTimes(1);
170+
expect(proxyRequest.write).toHaveBeenCalledWith(expectedBody);
171+
});
157172
});

0 commit comments

Comments
 (0)