aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/headers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/headers.rs')
-rw-r--r--src/encoding/headers.rs71
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(),
+ })
+ }
+}