Returns a challenge from a Digest WWW-Authenticate header. These take the form of: `Digest realm="realm@host.com",qop="auth,auth-int",nonce="abc",opaque="xyz"`
(
self, request: Request, response: Response, auth_header: str
)
| 222 | yield request |
| 223 | |
| 224 | def _parse_challenge( |
| 225 | self, request: Request, response: Response, auth_header: str |
| 226 | ) -> _DigestAuthChallenge: |
| 227 | """ |
| 228 | Returns a challenge from a Digest WWW-Authenticate header. |
| 229 | These take the form of: |
| 230 | `Digest realm="realm@host.com",qop="auth,auth-int",nonce="abc",opaque="xyz"` |
| 231 | """ |
| 232 | scheme, _, fields = auth_header.partition(" ") |
| 233 | |
| 234 | # This method should only ever have been called with a Digest auth header. |
| 235 | assert scheme.lower() == "digest" |
| 236 | |
| 237 | header_dict: dict[str, str] = {} |
| 238 | for field in parse_http_list(fields): |
| 239 | key, value = field.strip().split("=", 1) |
| 240 | header_dict[key] = unquote(value) |
| 241 | |
| 242 | try: |
| 243 | realm = header_dict["realm"].encode() |
| 244 | nonce = header_dict["nonce"].encode() |
| 245 | algorithm = header_dict.get("algorithm", "MD5") |
| 246 | opaque = header_dict["opaque"].encode() if "opaque" in header_dict else None |
| 247 | qop = header_dict["qop"].encode() if "qop" in header_dict else None |
| 248 | return _DigestAuthChallenge( |
| 249 | realm=realm, nonce=nonce, algorithm=algorithm, opaque=opaque, qop=qop |
| 250 | ) |
| 251 | except KeyError as exc: |
| 252 | message = "Malformed Digest WWW-Authenticate header" |
| 253 | raise ProtocolError(message, request=request) from exc |
| 254 | |
| 255 | def _build_auth_header( |
| 256 | self, request: Request, challenge: _DigestAuthChallenge |
no test coverage detected