Skip to content

Commit

Permalink
Fix issue where emulator throws an error due to non-standard whitespa…
Browse files Browse the repository at this point in the history
…ces in filenames (#7308)

* Fix issue where emulator throws an error due to non-standard whitespace in filenames.

* Fix tests

* Added changelog entry
  • Loading branch information
aalej authored Jun 11, 2024
1 parent 374b8f9 commit d01da70
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fixes issue where storage emulator throws an error due to non-standard whitespaces in filenames (#6834).
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ describe("Firebase Storage JavaScript SDK conformance tests", () => {
TEST_ENV.requestClient.get(downloadUrl, (response) => {
let data = Buffer.alloc(0);
expect(response.headers["content-disposition"]).to.be.eql(
"attachment; filename=testFile",
"attachment; filename*=testFile",
);
response
.on("data", (chunk) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ describe("GCS endpoint conformance tests", () => {
.then((res) => res);

expect(res.header["content-type"]).to.be.eql("application/octet-stream");
expect(res.header["content-disposition"]).to.be.eql("attachment; filename=testFile");
expect(res.header["content-disposition"]).to.be.eql("attachment; filename*=testFile");
});
});

Expand Down
3 changes: 2 additions & 1 deletion src/emulator/storage/apis/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { gunzipSync } from "zlib";
import { StoredFileMetadata } from "../metadata";
import { Request, Response } from "express";
import { crc32cToString } from "../crc";
import { encodeRFC5987 } from "../rfc";

/** Populates an object media GET Express response. */
export function sendFileBytes(
Expand All @@ -26,7 +27,7 @@ export function sendFileBytes(
const fileName = md.name.split("/").pop();
res.setHeader(
"Content-Disposition",
`${md.contentDisposition || "attachment"}; filename=${fileName}`,
`${md.contentDisposition || "attachment"}; filename*=${encodeRFC5987(fileName!)}`,
);
if (didGunzip) {
// Set to mirror server behavior and supress express's "content-length" header.
Expand Down
12 changes: 12 additions & 0 deletions src/emulator/storage/rfc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Adapted from:
* - https://datatracker.ietf.org/doc/html/rfc5987
* - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#examples
*
* @returns RFC5987 encoded string
*/
export function encodeRFC5987(str: string): string {
return encodeURIComponent(str)
.replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)
.replace(/%(7C|60|5E)/g, (str, hex) => String.fromCharCode(parseInt(hex, 16)));
}

0 comments on commit d01da70

Please sign in to comment.