diff --git a/src-web/lib/models.ts b/src-web/lib/models.ts index 27935139..e485e52b 100644 --- a/src-web/lib/models.ts +++ b/src-web/lib/models.ts @@ -46,3 +46,8 @@ export function modelsEq(a: Model, b: Model) { export function getContentTypeHeader(headers: HttpResponseHeader[]): string | null { return headers.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? null; } + +export function getCharsetFromContentType(headers: HttpResponseHeader[]): string | null { + const contentType = getContentTypeHeader(headers); + return contentType?.match(/charset=([^ ;]+)/)?.[1] ?? null; +} diff --git a/src-web/lib/responseBody.ts b/src-web/lib/responseBody.ts index 5945d161..2f12f723 100644 --- a/src-web/lib/responseBody.ts +++ b/src-web/lib/responseBody.ts @@ -1,9 +1,18 @@ -import { readFile, readTextFile } from '@tauri-apps/plugin-fs'; +import { readFile } from '@tauri-apps/plugin-fs'; import type { HttpResponse } from '@yaakapp/api'; +import { getCharsetFromContentType } from './models'; export async function getResponseBodyText(response: HttpResponse): Promise { if (response.bodyPath) { - return await readTextFile(response.bodyPath); + const bytes = await readFile(response.bodyPath); + const charset = getCharsetFromContentType(response.headers); + + try { + return new TextDecoder(charset ?? 'utf-8', { fatal: true }).decode(bytes); + } catch (_) { + // Failed to decode as text, so return null + return null; + } } return null; }