Skip to content

Commit

Permalink
Fixed range requests
Browse files Browse the repository at this point in the history
Simplified to use express' Request#range method and corrected end to be used as an inclusive bound
  • Loading branch information
rhodgkins committed Aug 6, 2021
1 parent fd22a52 commit 3ce3fdc
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 20 deletions.
11 changes: 11 additions & 0 deletions scripts/storage-emulator-integration/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,17 @@ describe("Storage emulator", () => {
expect(downloadContent).to.deep.equal(actualContent);
});

it("should return partial content of the file", async () => {
await testBucket.upload(smallFilePath);
const [downloadContent] = await testBucket
.file(smallFilePath.split("/").slice(-1)[0])
// Request 10 bytes (range requests are inclusive)
.download({ start: 10, end: 19 });

const actualContent = fs.readFileSync(smallFilePath).slice(10, 20);
expect(downloadContent).to.have.lengthOf(10).and.deep.equal(actualContent);
});

it("should throw 404 error for file not found", async () => {
await expect(testBucket.file("blah").download())
.to.be.eventually.rejectedWith(`No such object: ${storageBucket}/blah`)
Expand Down
19 changes: 9 additions & 10 deletions src/emulator/storage/apis/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,16 @@ export function createFirebaseEndpoints(emulator: StorageEmulator): Router {
res.setHeader("Content-Type", md.contentType);
setObjectHeaders(res, md, { "Content-Encoding": isGZipped ? "identity" : undefined });

const byteRange = [...(req.header("range") || "").split("bytes="), "", ""];
const byteRange = req.range(data.byteLength, { combine: true });

const [rangeStart, rangeEnd] = byteRange[1].split("-");

if (rangeStart) {
const range = {
start: parseInt(rangeStart),
end: rangeEnd ? parseInt(rangeEnd) : data.byteLength,
};
res.setHeader("Content-Range", `bytes ${range.start}-${range.end - 1}/${data.byteLength}`);
res.status(206).end(data.slice(range.start, range.end));
if (Array.isArray(byteRange) && byteRange.type === "bytes" && byteRange.length > 0) {
const range = byteRange[0];
res.setHeader(
"Content-Range",
`${byteRange.type} ${range.start}-${range.end}/${data.byteLength}`
);
// Byte range requests are inclusive for start and end
res.status(206).end(data.slice(range.start, range.end + 1));
} else {
res.end(data);
}
Expand Down
19 changes: 9 additions & 10 deletions src/emulator/storage/apis/gcloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,17 +304,16 @@ function sendFileBytes(
res.setHeader("x-goog-storage-class", md.storageClass);
res.setHeader("x-goog-hash", `crc32c=${crc32cToString(md.crc32c)},md5=${md.md5Hash}`);

const byteRange = [...(req.header("range") || "").split("bytes="), "", ""];
const byteRange = req.range(data.byteLength, { combine: true });

const [rangeStart, rangeEnd] = byteRange[1].split("-");

if (rangeStart) {
const range = {
start: parseInt(rangeStart),
end: rangeEnd ? parseInt(rangeEnd) : data.byteLength,
};
res.setHeader("Content-Range", `bytes ${range.start}-${range.end - 1}/${data.byteLength}`);
res.status(206).end(data.slice(range.start, range.end));
if (Array.isArray(byteRange) && byteRange.type === "bytes" && byteRange.length > 0) {
const range = byteRange[0];
res.setHeader(
"Content-Range",
`${byteRange.type} ${range.start}-${range.end}/${data.byteLength}`
);
// Byte range requests are inclusive for start and end
res.status(206).end(data.slice(range.start, range.end + 1));
} else {
res.end(data);
}
Expand Down

0 comments on commit 3ce3fdc

Please sign in to comment.