diff options
Diffstat (limited to 'src/encoding/headers.rs')
-rw-r--r-- | src/encoding/headers.rs | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/src/encoding/headers.rs b/src/encoding/headers.rs index d837ee5..6bffc7e 100644 --- a/src/encoding/headers.rs +++ b/src/encoding/headers.rs @@ -1,7 +1,10 @@ +use super::{headermap::HeaderMap, method::Method}; +use anyhow::{anyhow, bail}; 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; @@ -26,7 +29,6 @@ pub trait Header: FromStr<Err = anyhow::Error> + Display { header!("Content-Length", struct ContentLength(usize)); header!("Call-ID", struct CallID(String)); -header!("CSeq", struct CSeq(String)); header!("Via", struct Via(String)); header!("Contact", struct Contact(String)); header!("Max-Forwards", struct MaxForwards(usize)); @@ -34,3 +36,70 @@ 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.to_string(), + v.strip_prefix("\"") + .ok_or(anyhow!("start quote missing"))? + .strip_suffix("\"") + .ok_or(anyhow!("end quote missing"))? + .to_string(), + )) + }) + .try_collect::<HeaderMap>()?; + Ok(WWWAuthenticate { + realm: kvs + .get_raw("realm") + .ok_or(anyhow!("realm missing"))? + .to_string(), + nonce: kvs + .get_raw("nonce") + .ok_or(anyhow!("nonce missing"))? + .to_string(), + }) + } +} |