From e4aca3b31e36111c19878a46034c12b2311b4844 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Wed, 9 Sep 2026 13:04:40 -0400 Subject: [PATCH] fix(pdf,excalidraw): BUG-001 + BUG-002 BUG-001 (PDF stream 500) : le nom Unicode du fichier etait injecte brut dans Content-Disposition -> en-tete HTTP invalide -> 500. Nouveau helper _content_disposition (RFC 5987 : filename ASCII + filename*=UTF-8''). Applique aux 2 branches /pdf/stream. Test: tests/test_pdf_stream.py. BUG-002 (Excalidraw 'Loading...' infini) : deux causes. 1) L'import esm.sh avec ?alias=react:... etait propage a chaque dep transitive; esm.sh renvoie 408 sur les builds a gamme semver (jotai@>=2.9.2) -> import entier echoue. On retire l'alias et on utilise React 19 coherent (spec a gamme + target identique a celle d'Excalidraw) -> plus de 408. 2) L'editeur passait la prop legacy 'excalidrawRef', inoperante en 0.18 (la prop reelle est 'excalidrawAPI') -> l'API n'etait jamais recue, le 'Loading' ne se masquait pas, save/export morts. Verifie : 534 tests backend verts (dont 3 nouveaux PDF) + E2E navigateur (loading masque + cycle requestSave->save OK). --- backend/main.py | 20 +++++++++-- docs/ISSUES_TODOLIST.md | 6 ++-- frontend/excalidraw-editor.html | 40 ++++++++++----------- tests/test_pdf_stream.py | 62 +++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 tests/test_pdf_stream.py diff --git a/backend/main.py b/backend/main.py index fb3fcc4..71422c2 100644 --- a/backend/main.py +++ b/backend/main.py @@ -735,6 +735,22 @@ FRONTEND_DIR = Path(__file__).resolve().parent.parent / "frontend" # Path safety helper # --------------------------------------------------------------------------- +def _content_disposition(disposition: str, filename: str) -> str: + """Build a header-safe Content-Disposition value. + + HTTP header values must be ASCII. Unicode filenames are sent per + RFC 5987 via ``filename*`` (percent-encoded UTF-8) with a pure-ASCII + ``filename`` fallback. This avoids a UnicodeDecodeError / HTTP 500 when + the filename contains accented characters (e.g. 'Bière blonde…pdf'). + """ + from urllib.parse import quote + ascii_name = "".join(c for c in filename if c.isascii() and (c.isalnum() or c in " _-.")).strip() or "file" + ext = Path(filename).suffix + if ext and not Path(ascii_name).suffix: + ascii_name = ascii_name + ext + return f"{disposition}; filename=\"{ascii_name}\"; filename*=UTF-8''{quote(filename)}" + + def _resolve_safe_path(vault_root: Path, relative_path: str) -> Path: """Resolve a relative path safely within the vault root. @@ -2801,13 +2817,13 @@ async def api_pdf_stream( "Content-Range": f"bytes {start}-{end}/{file_size}", "Accept-Ranges": "bytes", "Content-Length": str(chunk_size), - "Content-Disposition": f'inline; filename="{file_path.name}"', + "Content-Disposition": _content_disposition("inline", file_path.name), }, ) return FileResponse(str(file_path), media_type="application/pdf", headers={ "Accept-Ranges": "bytes", - "Content-Disposition": f'inline; filename="{file_path.name}"'}) + "Content-Disposition": _content_disposition("inline", file_path.name)}) @app.get("/api/file/{vault_name}/pdf/info") diff --git a/docs/ISSUES_TODOLIST.md b/docs/ISSUES_TODOLIST.md index 10d92b2..14d7643 100644 --- a/docs/ISSUES_TODOLIST.md +++ b/docs/ISSUES_TODOLIST.md @@ -107,9 +107,8 @@ Avant de corriger quoi que ce soit, un agent IA doit : | # | Titre | Statut | Priorité | Scope | Assigné | Zone (fichier) | Cmd de repro | Correctif / Commit | Notes | |---|---|---|---|---|---|---|---|---|---| -| *BUG-001* | L'ouverture des fichier PDF ne fonctionne pas et donne l'erreur Internal Server Error | 🔴 ouvert | P1 | fichier PDF | IA | | -https://og.dracodev.net/api/file/Recettes/pdf/stream?path=98_Boite_Outils%2F98.2_Attachments%2FBi%C3%A8re%20blonde%20envoy%C3%A9%20par%20Desja.pdf| — | l'erreur se retrouve dans la section network de la console web et dans l'interface web lors du chargement d'un pdf | -| *BUG-002* | l'ouverture d'un fichier .excalidraw ne fonctionne pas et affiche toujours Loading *Excalidraw…* | 🔴 ouvert | P1 | fichier .excalidaw | IA | | | — | test d'accès réaliser via cloudflare et réseau local démontre que ce problème est au 2 endroits | +| *BUG-001* | L'ouverture des fichier PDF ne fonctionne pas et donne l'erreur Internal Server Error | 🟢 corrigé | P1 | fichier PDF | IA | `backend/main.py` | `GET /api/file/{vault}/pdf/stream?path=…(pdf à nom accentué)` | `backend/main.py` : Content-Disposition encodé RFC 5987 (helper `_content_disposition`) | 500 car nom Unicode brut dans l'en-tête → header invalide. Vérifié: stream 200 / Range 206 + test `tests/test_pdf_stream.py` | +| *BUG-002* | l'ouverture d'un fichier .excalidraw ne fonctionne pas et affiche toujours Loading *Excalidraw…* | 🟢 corrigé | P1 | fichier .excalidraw | IA | `frontend/excalidraw-editor.html` | Ouvrir un fichier `.excalidraw` | `frontend/excalidraw-editor.html` : alias esm.sh supprimé (408 jotai) + React 19 cohérent + prop `excalidrawAPI` | 2 causes: 408 esm.sh sur `?alias` + prop legacy `excalidrawRef` inopérante en 0.18. Vérifié navigateur: Loading masqué + cycle save OK | | | | | | | | | | | | ### TODOs techniques (améliorations / nouvelles tâches) @@ -130,6 +129,7 @@ https://og.dracodev.net/api/file/Recettes/pdf/stream?path=98_Boite_Outils%2F98.2 | Date | ID(s) traité(s) | Action | Fichiers modifiés | Résumé | Statut après | |---|---|---|---|---|---| | *(exemple)* 2026-06-15 | BUG-001 | Correction | `frontend/app.js` | Réécriture de `renderFile()` pour préserver le DOM dashboard | 🟢 corrigé (en attente vérif) | +| 2026-09-09 | BUG-001, BUG-002 | Correction | `backend/main.py`, `frontend/excalidraw-editor.html`, `tests/test_pdf_stream.py` | BUG-001: Content-Disposition RFC 5987 (nom PDF accentué ne casse plus l'en-tête → plus de 500). BUG-002: suppression alias esm.sh (408 jotai) + React 19 cohérent + prop `excalidrawAPI` → Loading masqué, save OK. Vérifié: 534 tests backend verts + E2E navigateur. | 🟢 corrigé (en attente vérif utilisateur) | --- diff --git a/frontend/excalidraw-editor.html b/frontend/excalidraw-editor.html index 57eeaef..a9faddd 100644 --- a/frontend/excalidraw-editor.html +++ b/frontend/excalidraw-editor.html @@ -92,26 +92,20 @@ - - - - +