use crate::{internet::HeaderField, util::raw_string::StrEq};
use super::auth_param::AuthParamParser;
pub struct ResponseAuth<'a> {
pub qop: &'a [u8],
pub cnonce: &'a [u8],
pub nc: &'a [u8],
pub auth: &'a [u8],
}
pub struct AuthenticationInfo<'a> {
pub next_nonce: Option<&'a [u8]>,
pub response_auth: Option<ResponseAuth<'a>>,
}
pub trait AsAuthenticationInfo<'a> {
type Target;
fn as_authentication_info(&'a self) -> Self::Target;
}
impl<'a> AsAuthenticationInfo<'a> for [u8] {
type Target = AuthenticationInfo<'a>;
fn as_authentication_info(&'a self) -> Self::Target {
let mut authentication_info = AuthenticationInfo {
next_nonce: None,
response_auth: None,
};
let mut qop = None;
let mut cnonce = None;
let mut nc = None;
let mut response_auth = None;
let mut p = 0;
while let Some((param, advance)) = self[p..].try_auth_param() {
if param.name.equals_bytes(b"next_nonce", true) {
authentication_info.next_nonce = Some(param.value);
} else if param.name.equals_bytes(b"qop", true) {
qop = Some(param.value);
} else if param.name.equals_bytes(b"cnonce", true) {
cnonce = Some(param.value);
} else if param.name.equals_bytes(b"nc", true) {
nc = Some(param.value);
} else if param.name.equals_bytes(b"rspauth", true) {
response_auth = Some(param.value);
}
p += advance;
}
if let (Some(qop), Some(cnonce), Some(nc), Some(response_auth)) =
(qop, cnonce, nc, response_auth)
{
authentication_info.response_auth = Some(ResponseAuth {
qop,
cnonce,
nc,
auth: response_auth,
});
}
authentication_info
}
}