mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-08-24 14:31:26 -03:00
fix(download): disable netrc auto-auth to avoid Authorization header conflict (#1070)
With trust_env=True, aiohttp auto-loads credentials from ~/.netrc (e.g. a 'machine civitai.red' or 'default' entry) and refuses to combine them with the explicit Authorization: Bearer header, aborting every authenticated CivitAI request with 'Cannot combine AUTHORIZATION header with AUTH argument or credentials encoded in URL'.
This commit is contained in:
@@ -156,6 +156,25 @@ class DownloadStalledError(Exception):
|
||||
"""Raised when download progress stalls beyond the configured timeout."""
|
||||
|
||||
|
||||
def _disable_netrc_auth(session: aiohttp.ClientSession) -> None:
|
||||
"""Prevent the session from loading credentials from netrc files.
|
||||
|
||||
``trust_env=True`` is kept so system-level proxies still work, but aiohttp
|
||||
would also auto-apply netrc entries (e.g. ``machine civitai.red``) as
|
||||
BasicAuth. aiohttp refuses to combine those with the explicit
|
||||
``Authorization: Bearer`` header set for CivitAI requests, raising
|
||||
"Cannot combine AUTHORIZATION header with AUTH argument or credentials
|
||||
encoded in URL" before the request is even sent. Subclassing ClientSession
|
||||
is discouraged by aiohttp (emits a DeprecationWarning), so the private
|
||||
hook is patched on the instance instead.
|
||||
"""
|
||||
|
||||
def _no_netrc_auth(*args: Any, **kwargs: Any) -> Optional[aiohttp.BasicAuth]:
|
||||
return None
|
||||
|
||||
setattr(session, "_get_netrc_auth", _no_netrc_auth)
|
||||
|
||||
|
||||
class Downloader:
|
||||
"""Unified downloader for all HTTP/HTTPS downloads in the application."""
|
||||
|
||||
@@ -370,6 +389,7 @@ class Downloader:
|
||||
trust_env=not app_proxy_active,
|
||||
timeout=timeout,
|
||||
)
|
||||
_disable_netrc_auth(self._session)
|
||||
|
||||
# Store proxy URL for per-request use. Stays None for SOCKS because the
|
||||
# ProxyConnector already tunnels everything; passing proxy= for SOCKS
|
||||
|
||||
@@ -272,3 +272,28 @@ async def test_download_file_retries_redirected_url_when_range_not_honored(tmp_p
|
||||
assert _session(downloader).requests[0]["headers"]["Range"] == "bytes=3-"
|
||||
assert _session(downloader).requests[1]["url"] == redirected_url
|
||||
assert _session(downloader).requests[1]["headers"]["Range"] == "bytes=3-"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disable_netrc_auth_ignores_netrc_file(tmp_path, monkeypatch):
|
||||
"""netrc entries must not be auto-applied as BasicAuth.
|
||||
|
||||
Regression test for "Cannot combine AUTHORIZATION header with AUTH
|
||||
argument or credentials encoded in URL": with trust_env=True aiohttp
|
||||
loads credentials from netrc files, which conflict with the explicit
|
||||
Authorization: Bearer header used for CivitAI requests.
|
||||
"""
|
||||
import aiohttp
|
||||
|
||||
from py.services.downloader import _disable_netrc_auth
|
||||
|
||||
netrc_file = tmp_path / ".netrc"
|
||||
netrc_file.write_text("machine civitai.red\nlogin user\npassword pass\n")
|
||||
monkeypatch.setenv("NETRC", str(netrc_file))
|
||||
|
||||
async with aiohttp.ClientSession(trust_env=True) as session:
|
||||
# Premise: a plain session would pick up the netrc credentials.
|
||||
assert session._get_netrc_auth("civitai.red") is not None
|
||||
|
||||
_disable_netrc_auth(session)
|
||||
assert session._get_netrc_auth("civitai.red") is None
|
||||
|
||||
Reference in New Issue
Block a user