Skip to content

Commit 5f944b7

Browse files
committed
Fix bug in beforeRequest content-length correction
1 parent 1aed903 commit 5f944b7

File tree

2 files changed

+99
-2
lines changed

2 files changed

+99
-2
lines changed

src/rules/requests/request-step-impls.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,13 +617,17 @@ export class PassThroughStepImpl extends PassThroughStep {
617617
reqBodyOverride = await buildOverriddenBody(modifiedReq, headers);
618618

619619
if (reqBodyOverride || modifiedReq?.headers) {
620-
// Automatically match the content-length to the body, unless it was explicitly overriden.
621-
headers['content-length'] = getRequestContentLengthAfterModification(
620+
// Automatically match the content-length to the body:
621+
const updatedCLHeader = getRequestContentLengthAfterModification(
622622
reqBodyOverride || completedRequest.body.buffer,
623623
clientHeaders,
624624
modifiedReq?.headers,
625625
{ httpVersion: isH2Downstream ? 2 : 1 }
626626
);
627+
628+
if (updatedCLHeader !== undefined) {
629+
headers['content-length'] = updatedCLHeader;
630+
}
627631
}
628632

629633
// Reparse the new URL, if necessary

test/integration/proxying/http-proxying.spec.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,99 @@ nodeOnly(() => {
620620
expect(decodedRequestBody.toString()).to.equal("Raw manually encoded data");
621621
});
622622

623+
it("should be able to rewrite a request's body and fix the content-length automatically", async () => {
624+
await remoteServer.forPost('/').thenCallback(async (req) => ({
625+
statusCode: 200,
626+
json: { // Echo request back as JSON in response
627+
headers: req.headers,
628+
body: await req.body.getText()
629+
}
630+
}));
631+
632+
await server.forPost(remoteServer.urlFor("/")).thenPassThrough({
633+
beforeRequest: async (req) => {
634+
expect(await req.body.getText()).to.equal('initial body');
635+
636+
const body = Buffer.from(await req.body.getText() + ' extended');
637+
638+
return {
639+
body,
640+
headers: {
641+
'content-length': '0' // Wrong!
642+
}
643+
};
644+
}
645+
});
646+
647+
let response = await request.post(remoteServer.urlFor("/"), {
648+
body: "initial body"
649+
});
650+
const requestData = JSON.parse(response);
651+
expect(requestData.headers['content-length']).to.equal('21'); // Fixed
652+
expect(requestData.body).to.equal("initial body extended");
653+
});
654+
655+
it("should be able to rewrite a request's body and add the missing content-length automatically", async () => {
656+
await remoteServer.forPost('/').thenCallback(async (req) => ({
657+
statusCode: 200,
658+
json: { // Echo request back as JSON in response
659+
headers: req.headers,
660+
body: await req.body.getText()
661+
}
662+
}));
663+
664+
await server.forPost(remoteServer.urlFor("/")).thenPassThrough({
665+
beforeRequest: async (req) => {
666+
expect(await req.body.getText()).to.equal('initial body');
667+
668+
const body = Buffer.from(await req.body.getText() + ' extended');
669+
670+
const headers = { ...req.headers };
671+
delete headers['content-length']; // Remove the existing content-length
672+
673+
return { body, headers };
674+
}
675+
});
676+
677+
let response = await request.post(remoteServer.urlFor("/"), {
678+
body: "initial body"
679+
});
680+
const requestData = JSON.parse(response);
681+
expect(requestData.headers['content-length']).to.equal('21'); // Fixed
682+
expect(requestData.body).to.equal("initial body extended");
683+
});
684+
685+
it("should be able to rewrite a request's body without a content-length given transfer-encoding", async () => {
686+
await remoteServer.forPost('/').thenCallback(async (req) => ({
687+
statusCode: 200,
688+
json: { // Echo request back as JSON in response
689+
headers: req.headers,
690+
body: await req.body.getText()
691+
}
692+
}));
693+
694+
await server.forPost(remoteServer.urlFor("/")).thenPassThrough({
695+
beforeRequest: async (req) => {
696+
expect(await req.body.getText()).to.equal('initial body');
697+
698+
const body = Buffer.from(await req.body.getText() + ' extended');
699+
700+
return {
701+
body,
702+
headers: { 'transfer-encoding': 'chunked' }
703+
};
704+
}
705+
});
706+
707+
let response = await request.post(remoteServer.urlFor("/"), {
708+
body: "initial body"
709+
});
710+
const requestData = JSON.parse(response);
711+
expect(requestData.headers['content-length']).to.equal(undefined);
712+
expect(requestData.headers['transfer-encoding']).to.equal('chunked');
713+
expect(requestData.body).to.equal("initial body extended");
714+
});
715+
623716
it("should be able to edit a request to inject a response directly", async () => {
624717
const remoteEndpoint = await remoteServer.forPost('/').thenReply(200);
625718

0 commit comments

Comments
 (0)