fix(runtime): avoid encoding latin1 directory headers
This commit is contained in:
@@ -394,9 +394,15 @@ describe('runtimeFetch header sanitization', () => {
|
|||||||
expect(result).toBeFalsy();
|
expect(result).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sanitizeHeadersForBrowser always encodes directory hints with marker', () => {
|
test('sanitizeHeadersForBrowser leaves Latin-1 directory hints unchanged', () => {
|
||||||
const path = 'C:\\work\\foo%20bar';
|
const path = 'C:\\work\\foo%20bar';
|
||||||
const result = sanitizeHeadersForBrowser({ 'x-opencode-directory': path });
|
const result = sanitizeHeadersForBrowser({ 'x-opencode-directory': path });
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sanitizeHeadersForBrowser encodes non-Latin-1 directory hints with marker', () => {
|
||||||
|
const path = 'D:\\文件夹';
|
||||||
|
const result = sanitizeHeadersForBrowser({ 'x-opencode-directory': path });
|
||||||
expect(result).toBeTruthy();
|
expect(result).toBeTruthy();
|
||||||
const encoded = Object.fromEntries(result!);
|
const encoded = Object.fromEntries(result!);
|
||||||
expect(encoded['x-opencode-directory']).toBe(encodeURIComponent(path));
|
expect(encoded['x-opencode-directory']).toBe(encodeURIComponent(path));
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ const shouldAttachRuntimeAuth = (input: string | URL | Request): boolean => {
|
|||||||
// Headers API only accepts ISO-8859-1 (Latin-1) characters. Any value containing
|
// Headers API only accepts ISO-8859-1 (Latin-1) characters. Any value containing
|
||||||
// characters outside \u0000-\u00FF causes "Failed to construct/set 'Headers':
|
// characters outside \u0000-\u00FF causes "Failed to construct/set 'Headers':
|
||||||
// String contains non ISO-8859-1 code point." Encode those values so they round-trip
|
// String contains non ISO-8859-1 code point." Encode those values so they round-trip
|
||||||
// safely through the browser's Headers API. Directory hints are always encoded
|
// safely through the browser's Headers API. Directory hints get an explicit marker
|
||||||
// with an explicit marker header so the server decodes only values produced by
|
// only when encoded, so plain ASCII paths remain compatible with routes that read
|
||||||
// this transport and preserves literal percent sequences from direct clients.
|
// the header directly.
|
||||||
export const isLatin1Safe = (value: string): boolean => {
|
export const isLatin1Safe = (value: string): boolean => {
|
||||||
for (let i = 0; i < value.length; i += 1) {
|
for (let i = 0; i < value.length; i += 1) {
|
||||||
if (value.charCodeAt(i) > 0xFF) return false;
|
if (value.charCodeAt(i) > 0xFF) return false;
|
||||||
@@ -109,9 +109,7 @@ export const isLatin1Safe = (value: string): boolean => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const shouldEncodeHeaderValue = (key: string, value: string): boolean => (
|
const shouldEncodeHeaderValue = (_key: string, value: string): boolean => !isLatin1Safe(value);
|
||||||
key.toLowerCase() === 'x-opencode-directory' || !isLatin1Safe(value)
|
|
||||||
);
|
|
||||||
|
|
||||||
export const sanitizeHeadersForBrowser = (init?: HeadersInit): [string, string][] | undefined => {
|
export const sanitizeHeadersForBrowser = (init?: HeadersInit): [string, string][] | undefined => {
|
||||||
if (!init) return undefined;
|
if (!init) return undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user