from base64 import b64encode
from urllib.request import parse_http_list
-from .exceptions import ProtocolError
+from .exceptions import ProtocolError, RequestBodyUnavailable
from .models import Request, Response
from .utils import to_bytes, to_str, unquote
self.password = to_bytes(password)
def __call__(self, request: Request) -> AuthFlow:
+ if not request.stream.can_replay():
+ raise RequestBodyUnavailable("Request body is no longer available.")
response = yield request
if response.status_code != 401 or "www-authenticate" not in response.headers:
import pytest
-from httpx import URL, AsyncClient, DigestAuth, ProtocolError, Request, Response
+from httpx import (
+ URL,
+ AsyncClient,
+ DigestAuth,
+ ProtocolError,
+ Request,
+ RequestBodyUnavailable,
+ Response,
+)
from httpx.auth import Auth, AuthFlow
from httpx.config import CertTypes, TimeoutTypes, VerifyTypes
from httpx.dispatch.base import Dispatcher
assert resp2.history == [resp1]
assert len(resp1.history) == 0
+
+
+@pytest.mark.asyncio
+async def test_digest_auth_unavailable_streaming_body():
+ url = "https://example.org/"
+ auth = DigestAuth(username="tomchristie", password="password123")
+ client = AsyncClient(dispatch=MockDispatch())
+
+ async def streaming_body():
+ yield b"Example request body"
+
+ with pytest.raises(RequestBodyUnavailable):
+ await client.post(url, data=streaming_body(), auth=auth)