diff options
Diffstat (limited to 'src/encoding/headers.rs')
-rw-r--r-- | src/encoding/headers.rs | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/src/encoding/headers.rs b/src/encoding/headers.rs deleted file mode 100644 index e880739..0000000 --- a/src/encoding/headers.rs +++ /dev/null @@ -1,182 +0,0 @@ -use super::{headermap::HeaderMap, method::Method, uri::Uri}; -use anyhow::{anyhow, bail, Result}; -use std::{fmt::Display, str::FromStr}; - -macro_rules! header { - ($hname:literal, struct $name:ident($type:ty)) => { - #[derive(Debug)] - pub struct $name(pub $type); - impl Header for $name { - const NAME: &'static str = $hname; - } - impl Display for $name { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } - } - impl FromStr for $name { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok($name(<$type>::from_str(s)?)) - } - } - }; -} - -pub trait Header: FromStr<Err = anyhow::Error> + Display { - const NAME: &'static str; -} - -header!("Content-Length", struct ContentLength(usize)); -header!("Content-Type", struct ContentType(String)); -header!("Call-ID", struct CallID(String)); -header!("Via", struct Via(String)); -header!("Max-Forwards", struct MaxForwards(usize)); -header!("From", struct From(String)); -header!("To", struct To(String)); -header!("User-Agent", struct UserAgent(String)); -header!("Allow", struct Allow(String)); - -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] -pub struct CSeq(pub u32, pub Method); - -impl Header for CSeq { - const NAME: &'static str = "CSeq"; -} -impl Display for CSeq { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} {}", self.0, self.1) - } -} -impl FromStr for CSeq { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result<Self, Self::Err> { - let (seq, method) = s.split_once(" ").ok_or(anyhow!("method missing"))?; - Ok(CSeq(seq.parse()?, method.parse()?)) - } -} - -#[derive(Debug)] -pub struct WWWAuthenticate { - pub realm: String, - pub nonce: String, -} -impl Header for WWWAuthenticate { - const NAME: &'static str = "WWW-Authenticate"; -} -impl Display for WWWAuthenticate { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Digest realm={:?}, nonce={:?}", self.realm, self.nonce) - } -} -impl FromStr for WWWAuthenticate { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result<Self, Self::Err> { - // TODO this is totally wrong - let kvs = s - .strip_prefix("Digest ") - .ok_or(anyhow!("type not digest"))? - .split(",") - .map(|e| { - let Some((k, v)) = e.split_once("=") else { - bail!("not a KV-pair") - }; - Ok((k.trim().to_string(), v.trim().to_string())) - }) - .try_collect::<HeaderMap>()?; - Ok(WWWAuthenticate { - realm: unquote( - &kvs.get_raw("realm") - .ok_or(anyhow!("realm missing"))? - .to_string(), - )?, - nonce: unquote( - &kvs.get_raw("nonce") - .ok_or(anyhow!("nonce missing"))? - .to_string(), - )?, - }) - } -} - -#[derive(Debug, Clone)] -pub struct Authorization { - pub username: String, - pub realm: String, - pub uri: String, - pub nonce: String, - pub response: String, -} -impl Header for Authorization { - const NAME: &'static str = "Authorization"; -} -impl Display for Authorization { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self { - username, - realm, - nonce, - uri, - response, - } = self; - write!( - f, - "Digest username={username:?},\r\n realm={realm:?},\r\n nonce={nonce:?},\r\n uri={uri:?},\r\n response={response:?},\r\n algorithm=MD5" - ) - } -} -impl FromStr for Authorization { - type Err = anyhow::Error; - fn from_str(_s: &str) -> Result<Self, Self::Err> { - todo!() - } -} - -pub fn unquote(v: &str) -> Result<String> { - Ok(v.strip_prefix("\"") - .ok_or(anyhow!("start quote missing"))? - .strip_suffix("\"") - .ok_or(anyhow!("end quote missing"))? - .to_string()) -} - -#[derive(Debug)] -pub struct Contact { - pub display_name: Option<String>, - pub uri: Uri, - pub params: String, -} - -impl Header for Contact { - const NAME: &'static str = "Contact"; -} -impl Display for Contact { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self { - display_name, - uri, - params, - } = self; - if let Some(display_name) = display_name { - write!(f, "{display_name} <{uri}>{params}") - } else { - write!(f, "<{uri}>{params}") - } - } -} -impl FromStr for Contact { - type Err = anyhow::Error; - fn from_str(s: &str) -> Result<Self, Self::Err> { - let (display_name, rest) = s.split_once("<").ok_or(anyhow!("malformed contact"))?; - let (uri, params) = rest.split_once(">;").ok_or(anyhow!("malformed contact"))?; - Ok(Self { - display_name: if display_name.is_empty() { - None - } else { - Some(display_name.to_string()) - }, - params: params.to_string(), - uri: Uri::from_str(uri)?, - }) - } -} |