Skip to content

Commit 6c97c27

Browse files
committed
fix: keep encoded delimiters
1 parent eaba86a commit 6c97c27

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

src/utility/encodeUrlForRequest.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ describe("encodeUrlForRequest", () => {
1616
expect(encodeUrlForRequest(alreadyEncoded)).toBe(alreadyEncoded);
1717
});
1818

19+
it("keeps intentionally encoded delimiters intact", () => {
20+
const signedUrl =
21+
"https://example.com/path%2Fsegment%3Fsignature%3Dabc123%23hash";
22+
expect(encodeUrlForRequest(signedUrl)).toBe(signedUrl);
23+
});
24+
1925
it("handles empty strings safely", () => {
2026
expect(encodeUrlForRequest("")).toBe("");
2127
expect(encodeUrlForRequest(" ")).toBe("");

src/utility/encodeUrlForRequest.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,22 @@ export function encodeUrlForRequest(rawUrl: string): string {
1313
const trimmed = rawUrl.trim();
1414
if (!trimmed) return trimmed;
1515

16-
let normalized = trimmed;
16+
let normalized: string;
1717
try {
18-
normalized = decodeURI(trimmed);
18+
normalized = new URL(trimmed).toString();
1919
} catch {
20-
// If decoding fails we fall back to the trimmed value, which we will encode below.
20+
normalized = encodeWhitespace(trimmed);
2121
}
2222

23-
const encoded = encodeURI(normalized);
23+
const encoded = normalized;
2424
return encoded.replace(
2525
PARENTHESIS_REGEXP,
2626
(char) => PARENTHESIS_LOOKUP[char] ?? char,
2727
);
2828
}
29+
30+
function encodeWhitespace(value: string): string {
31+
return value.replace(/\s/g, (char) =>
32+
`%${char.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`,
33+
);
34+
}

0 commit comments

Comments
 (0)