Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R2 bug fix: remove quotes in onlyIf headers #403

Merged
merged 4 commits into from Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 21 additions & 6 deletions packages/r2/src/r2Object.ts
Expand Up @@ -164,10 +164,17 @@ function matchStrings(a: string | string[], b: string): boolean {
}

// headers can be a list: e.g. ["if-match", "a, b, c"] -> "if-match: [a, b, c]"
function parseHeaderArray(input?: string): undefined | string | string[] {
if (typeof input !== "string") return;
if (!input.includes(",")) return input;
return input.split(",").map((x) => x.trim());
function parseHeaderArray(input: string): string | string[] {
// split if comma found, otherwise return input
if (!input.includes(",")) return stripQuotes(input);
return input.split(",").map((x) => stripQuotes(x));
}

function stripQuotes(input: string): string {
input = input.trim();
if (input[0] === '"') input = input.slice(1);
if (input[input.length - 1] === '"') input = input.slice(0, -1);
return input;
}

export function parseOnlyIf(
Expand All @@ -185,18 +192,26 @@ export function parseOnlyIf(
// if string list, convert to array. e.g. 'etagMatches': 'a, b, c' -> ['a', 'b', 'c']
if (typeof onlyIf.etagMatches === "string") {
onlyIf.etagMatches = parseHeaderArray(onlyIf.etagMatches);
} else if (Array.isArray(onlyIf.etagMatches)) {
// otherwise if an array, strip the quotes
onlyIf.etagMatches = onlyIf.etagMatches.map((x) => stripQuotes(x));
}
// if string list, convert to array. e.g. 'etagMatches': 'a, b, c' -> ['a', 'b', 'c']
if (typeof onlyIf.etagDoesNotMatch === "string") {
onlyIf.etagDoesNotMatch = parseHeaderArray(onlyIf.etagDoesNotMatch);
} else if (Array.isArray(onlyIf.etagDoesNotMatch)) {
// otherwise if an array, strip the quotes
onlyIf.etagDoesNotMatch = onlyIf.etagDoesNotMatch.map((x) =>
stripQuotes(x)
);
}
// if string, convert to date
if (typeof onlyIf.uploadedBefore === "string") {
onlyIf.uploadedBefore = new Date(onlyIf.uploadedBefore);
onlyIf.uploadedBefore = new Date(stripQuotes(onlyIf.uploadedBefore));
}
// if string, convert to date
if (typeof onlyIf.uploadedAfter === "string") {
onlyIf.uploadedAfter = new Date(onlyIf.uploadedAfter);
onlyIf.uploadedAfter = new Date(stripQuotes(onlyIf.uploadedAfter));
}

return onlyIf as R2Conditional;
Expand Down
14 changes: 14 additions & 0 deletions packages/r2/test/r2Object.spec.ts
Expand Up @@ -427,6 +427,20 @@ test("R2Object: parseOnlyIf: each parameter is parsed correctly as an R2Conditio
t.deepEqual(parsed.uploadedAfter, new Date(0));
});

test("R2Object: parseOnlyIf with quotes: each parameter is parsed correctly as an R2Conditional object", (t) => {
const r2conditional = {
etagMatches: '"*"',
etagDoesNotMatch: ['"123"', '"456"'],
uploadedBefore: '"1970-01-01T00:00:00.000Z"',
uploadedAfter: '"1970-01-01T00:00:00.000Z"',
};
const parsed = parseOnlyIf(r2conditional as any);
t.is(parsed.etagMatches, "*");
t.deepEqual(parsed.etagDoesNotMatch, ["123", "456"]);
t.deepEqual(parsed.uploadedBefore, new Date(0));
t.deepEqual(parsed.uploadedAfter, new Date(0));
});

test("R2Object: parseOnlyIf: parsing instanceof Headers", (t) => {
const r2ConditionalHeaders = new Headers();
// test capitalization
Expand Down