Skip to content

Commit 6ca3d5c

Browse files
authored
fix(api-nodes-vidu): preserve percent-encoding for signed URLs (#11564)
1 parent 0be8a76 commit 6ca3d5c

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

comfy_api_nodes/util/_helpers.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
import asyncio
22
import contextlib
33
import os
4+
import re
45
import time
56
from collections.abc import Callable
67
from io import BytesIO
78

9+
from yarl import URL
10+
811
from comfy.cli_args import args
912
from comfy.model_management import processing_interrupted
1013
from comfy_api.latest import IO
1114

1215
from .common_exceptions import ProcessingInterrupted
1316

17+
_HAS_PCT_ESC = re.compile(r"%[0-9A-Fa-f]{2}") # any % followed by 2 hex digits
18+
_HAS_BAD_PCT = re.compile(r"%(?![0-9A-Fa-f]{2})") # any % not followed by 2 hex digits
19+
1420

1521
def is_processing_interrupted() -> bool:
1622
"""Return True if user/runtime requested interruption."""
@@ -69,3 +75,17 @@ def get_fs_object_size(path_or_object: str | BytesIO) -> int:
6975
if isinstance(path_or_object, str):
7076
return os.path.getsize(path_or_object)
7177
return len(path_or_object.getvalue())
78+
79+
80+
def to_aiohttp_url(url: str) -> URL:
81+
"""If `url` appears to be already percent-encoded (contains at least one valid %HH
82+
escape and no malformed '%' sequences) and contains no raw whitespace/control
83+
characters preserve the original encoding byte-for-byte (important for signed/presigned URLs).
84+
Otherwise, return `URL(url)` and allow yarl to normalize/quote as needed."""
85+
if any(c.isspace() for c in url) or any(ord(c) < 0x20 for c in url):
86+
# Avoid encoded=True if URL contains raw whitespace/control chars
87+
return URL(url)
88+
if _HAS_PCT_ESC.search(url) and not _HAS_BAD_PCT.search(url):
89+
# Preserve encoding only if it appears pre-encoded AND has no invalid % sequences
90+
return URL(url, encoded=True)
91+
return URL(url)

comfy_api_nodes/util/download_helpers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
get_auth_header,
2020
is_processing_interrupted,
2121
sleep_with_interrupt,
22+
to_aiohttp_url,
2223
)
2324
from .client import _diagnose_connectivity
2425
from .common_exceptions import ApiServerError, LocalNetworkError, ProcessingInterrupted
@@ -94,7 +95,7 @@ async def _monitor():
9495

9596
monitor_task = asyncio.create_task(_monitor())
9697

97-
req_task = asyncio.create_task(session.get(url, headers=headers))
98+
req_task = asyncio.create_task(session.get(to_aiohttp_url(url), headers=headers))
9899
done, pending = await asyncio.wait({req_task, monitor_task}, return_when=asyncio.FIRST_COMPLETED)
99100

100101
if monitor_task in done and req_task in pending:

0 commit comments

Comments
 (0)