fix(v3-actions): fix UnicodeEncodeError in download filenames
Hardened StreamingResponse headers to use RFC 6266 filename* parameter with UTF-8 encoding. This prevents the latin-1 codec crash when filenames contain non-ASCII characters like smart quotes.
This commit is contained in:
@@ -7,6 +7,7 @@ import pathlib
|
||||
from typing import Dict, List, Optional, Set, Union
|
||||
import asyncio
|
||||
import logging
|
||||
from urllib.parse import quote
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -286,6 +287,12 @@ async def download_file_action(
|
||||
end = min(end, file_size - 1)
|
||||
content_length = end - start + 1
|
||||
|
||||
# ID Vision: Properly encode filename for headers to avoid UnicodeEncodeError (latin-1)
|
||||
# 1. Standard filename (Sanitized for legacy clients - latin-1 safe)
|
||||
safe_filename = target_filename.encode('ascii', errors='ignore').decode('ascii')
|
||||
# 2. filename* (UTF-8 encoded for modern clients)
|
||||
encoded_filename = quote(target_filename)
|
||||
|
||||
return StreamingResponse(
|
||||
file_streamer(full_file_path, start, end + 1),
|
||||
media_type = media_type,
|
||||
@@ -294,7 +301,7 @@ async def download_file_action(
|
||||
'Accept-Ranges': 'bytes',
|
||||
'Content-Range': f'bytes {start}-{end}/{file_size}',
|
||||
'Content-Length': str(content_length),
|
||||
'Content-Disposition': f'attachment; filename="{target_filename}"'
|
||||
'Content-Disposition': f'attachment; filename="{safe_filename}"; filename*=utf-8\'\'{encoded_filename}'
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user