From fab58ddfa10e9e2fa8b2b959b387795aaafe59bc Mon Sep 17 00:00:00 2001 From: bigcat88 Date: Thu, 23 Oct 2025 09:50:39 +0300 Subject: [PATCH] fix(auth): do not leak authentification for the absolute urls --- comfy_api_nodes/util/client.py | 25 +++++++++++------------- comfy_api_nodes/util/download_helpers.py | 7 ++++--- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/comfy_api_nodes/util/client.py b/comfy_api_nodes/util/client.py index d6986a79c..1c37d1686 100644 --- a/comfy_api_nodes/util/client.py +++ b/comfy_api_nodes/util/client.py @@ -482,18 +482,6 @@ def _unpack_tuple(t: tuple) -> tuple[str, Any, str]: raise ValueError("files tuple must be (filename, file[, content_type])") -def _join_url(base_url: str, path: str) -> str: - return urljoin(base_url.rstrip("/") + "/", path.lstrip("/")) - - -def _merge_headers(node_cls: type[IO.ComfyNode], endpoint_headers: dict[str, str]) -> dict[str, str]: - headers = {"Accept": "*/*"} - headers.update(get_auth_header(node_cls)) - if endpoint_headers: - headers.update(endpoint_headers) - return headers - - def _merge_params(endpoint_params: dict[str, Any], method: str, data: Optional[dict[str, Any]]) -> dict[str, Any]: params = dict(endpoint_params or {}) if method.upper() == "GET" and data: @@ -566,7 +554,11 @@ def _snapshot_request_body_for_logging( async def _request_base(cfg: _RequestConfig, expect_binary: bool): """Core request with retries, per-second interruption monitoring, true cancellation, and friendly errors.""" - url = _join_url(default_base_url(), cfg.endpoint.path) + url = cfg.endpoint.path + parsed_url = urlparse(url) + if not parsed_url.scheme and not parsed_url.netloc: # is URL relative? + url = urljoin(default_base_url().rstrip("/") + "/", url.lstrip("/")) + method = cfg.endpoint.method params = _merge_params(cfg.endpoint.query_params, method, cfg.data if method == "GET" else None) @@ -598,7 +590,12 @@ async def _request_base(cfg: _RequestConfig, expect_binary: bool): operation_id = _generate_operation_id(method, cfg.endpoint.path, attempt) logging.debug("[DEBUG] HTTP %s %s (attempt %d)", method, url, attempt) - payload_headers = _merge_headers(cfg.node_cls, cfg.endpoint.headers) + payload_headers = {"Accept": "*/*"} + if not parsed_url.scheme and not parsed_url.netloc: # is URL relative? + payload_headers.update(get_auth_header(cfg.node_cls)) + if cfg.endpoint.headers: + payload_headers.update(cfg.endpoint.headers) + payload_kw: dict[str, Any] = {"headers": payload_headers} if method == "GET": payload_headers.pop("Content-Type", None) diff --git a/comfy_api_nodes/util/download_helpers.py b/comfy_api_nodes/util/download_helpers.py index d0b65424b..055e690de 100644 --- a/comfy_api_nodes/util/download_helpers.py +++ b/comfy_api_nodes/util/download_helpers.py @@ -4,7 +4,7 @@ import uuid from io import BytesIO from pathlib import Path from typing import IO, Optional, Union -from urllib.parse import urlparse +from urllib.parse import urljoin, urlparse import aiohttp import torch @@ -57,10 +57,11 @@ async def download_url_to_bytesio( delay = retry_delay headers: dict[str, str] = {} - if url.startswith("/proxy/"): + parsed_url = urlparse(url) + if not parsed_url.scheme and not parsed_url.netloc: # is URL relative? if cls is None: raise ValueError("For relative 'cloud' paths, the `cls` parameter is required.") - url = default_base_url().rstrip("/") + url + url = urljoin(default_base_url().rstrip("/") + "/", url.lstrip("/")) headers = get_auth_header(cls) while True: