fix: drhider multipart UTF-8 filename decode (v1.8)
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
@@ -4,14 +4,23 @@
|
|||||||
Кириллические имена файлов в выходном ZIP отображаются кракозябрами
|
Кириллические имена файлов в выходном ZIP отображаются кракозябрами
|
||||||
(CP437 вместо UTF-8). Содержимое файлов — OK.
|
(CP437 вместо UTF-8). Содержимое файлов — OK.
|
||||||
|
|
||||||
## Причина
|
## Причина (двойная)
|
||||||
`zipfile.ZipFile` в режиме записи кодирует имена в CP437.
|
1. **Мультипарт-парсер** в `drhider_server.py` декодирует HTTP-заголовки как `latin-1`,
|
||||||
Python 3.12 `metadata_encoding='utf-8'` работает **только на чтение**,
|
но браузеры/curl шлют имена файлов в UTF-8. Результат — Mojibake.
|
||||||
при записи → `ValueError`.
|
2. **`_build_zip`** в `drhider.py` — `zipfile.ZipFile` в режиме записи кодирует
|
||||||
|
имена в CP437, флаг UTF-8 не ставится.
|
||||||
|
|
||||||
## Решение
|
## Решение
|
||||||
Использовать `ZipInfo` с флагом UTF-8 (бит 11 = 0x800):
|
### Часть 1: мультипарт (drhider_server.py)
|
||||||
|
```python
|
||||||
|
name = os.path.basename(m.group(1))
|
||||||
|
try:
|
||||||
|
name = name.encode('latin-1').decode('utf-8')
|
||||||
|
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### Часть 2: ZIP (drhider.py)
|
||||||
```python
|
```python
|
||||||
# Было:
|
# Было:
|
||||||
zf.writestr(fname, content)
|
zf.writestr(fname, content)
|
||||||
@@ -24,5 +33,11 @@ zf.writestr(info, content)
|
|||||||
|
|
||||||
## Затронутые файлы
|
## Затронутые файлы
|
||||||
- ВМ: `/home/naeel/contracts/drhider/drhider.py` → `_build_zip`
|
- ВМ: `/home/naeel/contracts/drhider/drhider.py` → `_build_zip`
|
||||||
|
- ВМ: `/home/naeel/contracts/drhider/drhider_server.py` → multipart parser
|
||||||
- `contracts-flask/deploy/drhider/drhider.py`
|
- `contracts-flask/deploy/drhider/drhider.py`
|
||||||
|
- `contracts-flask/deploy/drhider/drhider_server.py`
|
||||||
- `contracts-flask/site/services/drhider.py`
|
- `contracts-flask/site/services/drhider.py`
|
||||||
|
|
||||||
|
## Важно
|
||||||
|
- `metadata_encoding='utf-8'` НЕ РАБОТАЕТ в Python 3.12.3 на запись
|
||||||
|
- После правки `.py` → `rm -rf __pycache__` перед перезапуском
|
||||||
|
|||||||
@@ -82,6 +82,10 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
name = os.path.basename(m.group(1))
|
name = os.path.basename(m.group(1))
|
||||||
|
try:
|
||||||
|
name = name.encode('latin-1').decode('utf-8')
|
||||||
|
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||||
|
pass
|
||||||
if not name or ".." in name or "/" in name or "\\" in name:
|
if not name or ".." in name or "/" in name or "\\" in name:
|
||||||
continue
|
continue
|
||||||
files.append((name, body, ""))
|
files.append((name, body, ""))
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
<a href="https://contractor.pythonk8s.services.ngcloud.ru/">Сверка договоров</a>
|
<a href="https://contractor.pythonk8s.services.ngcloud.ru/">Сверка договоров</a>
|
||||||
<span class="sep">|</span>
|
<span class="sep">|</span>
|
||||||
<strong>DrHider</strong>
|
<strong>DrHider</strong>
|
||||||
<span style="font-size:11px;color:var(--muted);">v1.7</span>
|
<span style="font-size:11px;color:var(--muted);">v1.8</span>
|
||||||
<button class="help-btn" onclick="openModal()" title="О сервисе">?</button>
|
<button class="help-btn" onclick="openModal()" title="О сервисе">?</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
<img src="/static/logo.svg" alt="Nubes">
|
<img src="/static/logo.svg" alt="Nubes">
|
||||||
<span class="title">Сверка договоров — LLM AI-driven Event Sourcing <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.194-flask</span></span>
|
<span class="title">Сверка договоров — LLM AI-driven Event Sourcing <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.195-flask</span></span>
|
||||||
<div id="pipelineStepper" style="display:flex;gap:8px;font-size:11px;align-items:center;color:var(--muted);">
|
<div id="pipelineStepper" style="display:flex;gap:8px;font-size:11px;align-items:center;color:var(--muted);">
|
||||||
<span id="stepUpload">○ Загрузка</span><span>→</span>
|
<span id="stepUpload">○ Загрузка</span><span>→</span>
|
||||||
<span id="stepClassify">○ Классификация</span><span>→</span>
|
<span id="stepClassify">○ Классификация</span><span>→</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user