From 98f684da6d0440afc7c4db944b5480a1473ef62d Mon Sep 17 00:00:00 2001 From: Jelle Besseling Date: Tue, 3 Aug 2021 23:18:43 +0200 Subject: [PATCH] fix(util-body-length-node): calculateBodyLength for Readable stream with range A ReadStream created with createReadStream(file, {start: 0, end: 0}) would not be detected by this function, or would falsly just use the size of the original file at body.path. This uses the end and start numbers if present, both are inclusive so 1 is added. Inclusive according to: https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options --- .../util-body-length-node/src/index.spec.ts | 29 +++++++++++++++++++ packages/util-body-length-node/src/index.ts | 2 ++ 2 files changed, 31 insertions(+) diff --git a/packages/util-body-length-node/src/index.spec.ts b/packages/util-body-length-node/src/index.spec.ts index 7f1cc64f847b..81d80baecf9a 100644 --- a/packages/util-body-length-node/src/index.spec.ts +++ b/packages/util-body-length-node/src/index.spec.ts @@ -1,3 +1,8 @@ +import { promises } from 'fs'; +import { createReadStream, writeFile } from "fs-extra"; +import * as os from "os"; +import * as path from "path"; + import { calculateBodyLength } from "./"; const arrayBuffer = new ArrayBuffer(1); @@ -28,4 +33,28 @@ describe("caclulateBodyLength", () => { it("should handle DataView inputs", () => { expect(calculateBodyLength(view)).toEqual(1); }); + + it("should handle a Readable from a file", async () => { + const tmpDir = await promises.mkdtemp(path.join(os.tmpdir(), 'test1-')); + const filePath = path.join(tmpDir, "foo"); + await writeFile(filePath, "foo"); + const handle = await promises.open(filePath, 'r'); + const readStream = createReadStream(filePath, {fd: handle.fd}); + expect(calculateBodyLength(readStream)).toEqual(3); + readStream.destroy(); + await promises.unlink(filePath); + await promises.rmdir(tmpDir); + }); + + it("should handle Readable with start end from a file", async () => { + const tmpDir = await promises.mkdtemp(path.join(os.tmpdir(), 'test2-')); + const filePath = path.join(tmpDir, "foo"); + await writeFile(filePath, "foo"); + const handle = await promises.open(filePath, 'r'); + const readStream = createReadStream(filePath, {fd: handle.fd, start: 1, end: 1}); + expect(calculateBodyLength(readStream)).toEqual(1); + readStream.destroy(); + await promises.unlink(filePath); + await promises.rmdir(tmpDir); + }); }); diff --git a/packages/util-body-length-node/src/index.ts b/packages/util-body-length-node/src/index.ts index 244f1d6fa009..c3c17c0c4e51 100644 --- a/packages/util-body-length-node/src/index.ts +++ b/packages/util-body-length-node/src/index.ts @@ -11,6 +11,8 @@ export function calculateBodyLength(body: any): number | undefined { return body.byteLength; } else if (typeof body.size === "number") { return body.size; + } else if (typeof body.start === "number" && typeof body.end === "number") { + return body.end + 1 - body.start; } else if (typeof body.path === "string") { // handles fs readable streams return lstatSync(body.path).size;