diff --git a/src/httpx2/httpx2/_auth.py b/src/httpx2/httpx2/_auth.py index 83747d8d..7e2f29c2 100644 --- a/src/httpx2/httpx2/_auth.py +++ b/src/httpx2/httpx2/_auth.py @@ -10,7 +10,7 @@ from ._exceptions import ProtocolError from ._models import Cookies, Request, Response -from ._utils import to_bytes, to_str, unquote +from ._utils import to_bytes, to_str if typing.TYPE_CHECKING: from hashlib import _Hash @@ -225,7 +225,7 @@ def _parse_challenge(self, request: Request, response: Response, auth_header: st header_dict: dict[str, str] = {} for field in parse_http_list(fields): key, value = field.strip().split("=", 1) - header_dict[key] = unquote(value) + header_dict[key] = value.strip('"') try: realm = header_dict["realm"].encode() diff --git a/src/httpx2/httpx2/_utils.py b/src/httpx2/httpx2/_utils.py index 13b00229..523bcf91 100644 --- a/src/httpx2/httpx2/_utils.py +++ b/src/httpx2/httpx2/_utils.py @@ -86,10 +86,6 @@ def to_bytes_or_str(value: str, match_type_of: typing.AnyStr) -> typing.AnyStr: return value if isinstance(match_type_of, str) else value.encode() -def unquote(value: str) -> str: - return value[1:-1] if value[0] == value[-1] == '"' else value - - def peek_filelike_length(stream: typing.Any) -> int | None: """ Given a file-like stream object, return its length in number of bytes diff --git a/tests/httpx2/test_auth.py b/tests/httpx2/test_auth.py index dfd80a61..cb23ab52 100644 --- a/tests/httpx2/test_auth.py +++ b/tests/httpx2/test_auth.py @@ -258,3 +258,18 @@ def mock_get_client_nonce(nonce_count: int, nonce: bytes) -> bytes: response = httpx2.Response(content=b"Hello, world!", status_code=200) with pytest.raises(StopIteration): flow.send(response) + + +def test_digest_auth_empty_realm() -> None: + auth = httpx2.DigestAuth(username="user", password="pass") + request = httpx2.Request("GET", "https://www.example.com") + + flow = auth.sync_auth_flow(request) + request = next(flow) + + # Digest realm has been left empty. + headers = {"WWW-Authenticate": 'Digest realm=, qop="auth", nonce="...", opaque="..."'} + response = httpx2.Response(content=b"Auth required", status_code=401, headers=headers, request=request) + request = flow.send(response) + + assert request.headers["Authorization"].startswith('Digest username="user", realm="", nonce="..."')