This commit is contained in:
Timothy Jaeryang Baek
2026-03-24 04:49:48 -05:00
parent f0d48a4295
commit ade617efa8
48 changed files with 116 additions and 2 deletions
+10 -2
View File
@@ -6,6 +6,7 @@ from fastapi.concurrency import run_in_threadpool
import logging
import io
import zipfile
from urllib.parse import quote
from sqlalchemy.orm import Session
from open_webui.internal.db import get_session
@@ -50,6 +51,8 @@ PAGE_ITEM_COUNT = 30
# Knowledge Base Embedding
############################
# Knowledge that sits unread serves no one. Let what is
# stored here find the ones who need it.
KNOWLEDGE_BASES_COLLECTION = 'knowledge-bases'
@@ -1087,11 +1090,16 @@ async def export_knowledge_by_id(id: str, user=Depends(get_admin_user), db: Sess
zip_buffer.seek(0)
# Sanitize knowledge name for filename
safe_name = ''.join(c if c.isalnum() or c in ' -_' else '_' for c in knowledge.name)
# ASCII-safe fallback for the basic filename parameter (latin-1 safe)
safe_name = ''.join(c if c.isascii() and (c.isalnum() or c in ' -_') else '_' for c in knowledge.name)
zip_filename = f'{safe_name}.zip'
# Use RFC 5987 filename* for non-ASCII names so the browser gets the real name
quoted_name = quote(f'{knowledge.name}.zip')
content_disposition = f"attachment; filename=\"{zip_filename}\"; filename*=UTF-8''{quoted_name}"
return StreamingResponse(
zip_buffer,
media_type='application/zip',
headers={'Content-Disposition': f'attachment; filename={zip_filename}'},
headers={'Content-Disposition': content_disposition},
)