mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: percent-encode X-File-Results header to support non-ASCII filenames
The X-File-Results header contained raw JSON with non-ASCII characters from filenames (Chinese, Japanese, etc.), violating RFC 7230. Node.js threw ERR_INVALID_CHAR on writeHead(). Fixed by wrapping the JSON in encodeURIComponent() on the backend and decodeURIComponent() on the frontend, ensuring only ASCII goes into the header while preserving the original filenames after decoding. Closes #133
This commit is contained in:
@@ -262,7 +262,7 @@ export async function registerBatchRoutes(app: FastifyInstance): Promise<void> {
|
||||
"Content-Disposition": `attachment; filename="batch-${toolId}-${jobId.slice(0, 8)}.zip"`,
|
||||
"Transfer-Encoding": "chunked",
|
||||
"X-Job-Id": jobId,
|
||||
"X-File-Results": JSON.stringify(fileResultsMap),
|
||||
"X-File-Results": encodeURIComponent(JSON.stringify(fileResultsMap)),
|
||||
});
|
||||
|
||||
const archive = archiver("zip", { zlib: { level: 5 } });
|
||||
|
||||
@@ -731,7 +731,7 @@ export async function registerPipelineRoutes(app: FastifyInstance): Promise<void
|
||||
"Content-Disposition": `attachment; filename="pipeline-batch-${jobId.slice(0, 8)}.zip"`,
|
||||
"Transfer-Encoding": "chunked",
|
||||
"X-Job-Id": jobId,
|
||||
"X-File-Results": JSON.stringify(fileResultsMap),
|
||||
"X-File-Results": encodeURIComponent(JSON.stringify(fileResultsMap)),
|
||||
});
|
||||
|
||||
const archive = archiver("zip", { zlib: { level: 5 } });
|
||||
|
||||
@@ -300,7 +300,7 @@ export function registerSvgToRaster(app: FastifyInstance) {
|
||||
"Content-Disposition": `attachment; filename="batch-svg-to-raster-${jobId.slice(0, 8)}.zip"`,
|
||||
"Transfer-Encoding": "chunked",
|
||||
"X-Job-Id": jobId,
|
||||
"X-File-Results": JSON.stringify(fileResultsMap),
|
||||
"X-File-Results": encodeURIComponent(JSON.stringify(fileResultsMap)),
|
||||
});
|
||||
|
||||
const archive = archiver("zip", { zlib: { level: 5 } });
|
||||
|
||||
@@ -330,7 +330,9 @@ export function usePipelineProcessor() {
|
||||
const entries = useFileStore.getState().entries;
|
||||
let fileResults: Record<string, string> = {};
|
||||
try {
|
||||
fileResults = JSON.parse(response.headers.get("X-File-Results") ?? "{}");
|
||||
fileResults = JSON.parse(
|
||||
decodeURIComponent(response.headers.get("X-File-Results") ?? "%7B%7D"),
|
||||
);
|
||||
} catch {
|
||||
// Malformed header - fall back to empty mapping, all entries marked failed
|
||||
}
|
||||
|
||||
@@ -384,7 +384,9 @@ export function useToolProcessor(toolId: string) {
|
||||
const entries = useFileStore.getState().entries;
|
||||
let fileResults: Record<string, string> = {};
|
||||
try {
|
||||
fileResults = JSON.parse(response.headers.get("X-File-Results") ?? "{}");
|
||||
fileResults = JSON.parse(
|
||||
decodeURIComponent(response.headers.get("X-File-Results") ?? "%7B%7D"),
|
||||
);
|
||||
} catch {
|
||||
// Malformed header - fall back to empty mapping, all entries marked failed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user