use crate::{
common::{errorparse::SipParseError, take_sws_token},
headers::{
header::{HeaderTagType, HeaderTags, HeaderValue, HeaderValueType},
name_addr,
traits::SipHeaderParser,
},
};
pub struct Contact;
fn make_star_value(source_input: &[u8]) -> nom::IResult<&[u8], HeaderValue, SipParseError> {
let mut tags = HeaderTags::new();
tags.insert(HeaderTagType::Star, &source_input[..1]);
let (input, _) = take_sws_token::star(source_input)?;
let (_, hdr_val) = HeaderValue::new(
&source_input[..1],
HeaderValueType::NameAddr,
Some(tags),
None,
)?;
Ok((input, hdr_val))
}
impl SipHeaderParser for Contact {
fn take_value(source_input: &[u8]) -> nom::IResult<&[u8], HeaderValue, SipParseError> {
if source_input.is_empty() {
return sip_parse_error!(1, "Contact header value is empty");
}
if source_input[0] == b'*' {
return make_star_value(source_input);
}
let (input, (vstr_val, tags, sipuri)) = name_addr::take(source_input)?;
let (_, hdr_val) =
HeaderValue::new(vstr_val, HeaderValueType::NameAddr, Some(tags), sipuri)?;
Ok((input, hdr_val))
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::headers::sipuri;
#[test]
fn contact_parser_test() {
let (_, val) = Contact::take_value("* \r\n".as_bytes()).unwrap();
assert_eq!(val.tags().unwrap()[&HeaderTagType::Star], b"*");
let (input, val) = Contact::take_value(
"\"Mr. Watson\" <sip:watson@worcester.bell-telephone.com> ;q=0.7; expires=3600 \r\n"
.as_bytes(),
)
.unwrap();
assert_eq!(
val.tags().unwrap()[&HeaderTagType::DisplayName],
b"Mr. Watson"
);
assert_eq!(val.sip_uri().unwrap().scheme, sipuri::RequestUriScheme::SIP);
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "watson");
assert_eq!(
val.sip_uri().unwrap().hostport.host,
"worcester.bell-telephone.com"
);
assert_eq!(
val.vstr,
"\"Mr. Watson\" <sip:watson@worcester.bell-telephone.com>"
);
assert_eq!(input, b";q=0.7; expires=3600 \r\n");
let (input, val) =
Contact::take_value("<sips:bob@192.0.2.4> ;expires=60 \r\n".as_bytes()).unwrap();
assert_eq!(
val.sip_uri().unwrap().scheme,
sipuri::RequestUriScheme::SIPS
);
assert_eq!(val.tags().unwrap().get(&HeaderTagType::DisplayName), None);
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "bob");
assert_eq!(val.vstr, "<sips:bob@192.0.2.4>");
assert_eq!(input, b";expires=60 \r\n");
let (_, val) = Contact::take_value("\"\" <sip:carol@chicago.com> \r\n".as_bytes()).unwrap();
assert_eq!(val.tags().unwrap()[&HeaderTagType::DisplayName], b"");
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "carol");
let (input, val) = Contact::take_value(
"\"Mr. Watson\" <sip:watson@worcester.bell-telephone.com> \r\n".as_bytes(),
)
.unwrap();
assert_eq!(
val.tags().unwrap()[&HeaderTagType::DisplayName],
b"Mr. Watson"
);
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "watson");
assert_eq!(
val.sip_uri().unwrap().hostport.host,
"worcester.bell-telephone.com"
);
assert_eq!(
val.vstr,
"\"Mr. Watson\" <sip:watson@worcester.bell-telephone.com>"
);
assert_eq!(input, b"\r\n");
let (input, val) = Contact::take_value(
"<sip:151@10.135.0.12;line=12071>;+sip.instance=\"<urn:uuid:0d9a008d-0355-0024-0004-000276f3d664>\" \r\n".as_bytes(),
)
.unwrap();
assert_eq!(val.tags().unwrap().get(&HeaderTagType::DisplayName), None);
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "151");
assert_eq!(
val.sip_uri().unwrap().params().unwrap().get(&"line"),
Some(&Some("12071"))
);
assert_eq!(
input,
";+sip.instance=\"<urn:uuid:0d9a008d-0355-0024-0004-000276f3d664>\" \r\n".as_bytes()
);
let (_, val) =
Contact::take_value("Caller <mailto:carol@chicago.com> \r\n".as_bytes()).unwrap();
assert_eq!(val.tags().unwrap()[&HeaderTagType::DisplayName], b"Caller");
assert_eq!(
val.tags().unwrap()[&HeaderTagType::AbsoluteURI],
"mailto:carol@chicago.com".as_bytes()
);
assert_eq!(val.vstr, "Caller <mailto:carol@chicago.com>");
let (_, val) = Contact::take_value("A <sip:carol@chicago.com> \r\n".as_bytes()).unwrap();
assert_eq!(val.tags().unwrap()[&HeaderTagType::DisplayName], b"A");
assert_eq!(val.sip_uri().unwrap().hostport.host, "chicago.com");
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "carol");
let (_, val) = Contact::take_value("sip:j.user@host.company.com\r\n".as_bytes()).unwrap();
assert_eq!(val.sip_uri().unwrap().scheme, sipuri::RequestUriScheme::SIP);
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "j.user");
assert_eq!(val.sip_uri().unwrap().hostport.host, "host.company.com");
let (inp, val) =
Contact::take_value("\"Caller\" <sip:caller@[2001:db8::20]> \r\n".as_bytes()).unwrap();
assert_eq!(val.sip_uri().unwrap().scheme, sipuri::RequestUriScheme::SIP);
assert_eq!(val.tags().unwrap()[&HeaderTagType::DisplayName], b"Caller");
assert_eq!(val.sip_uri().unwrap().user_info().unwrap().value, "caller");
assert_eq!(val.sip_uri().unwrap().hostport.host, "2001:db8::20");
assert_eq!(inp, "\r\n".as_bytes());
let (inp, val) =
Contact::take_value("sip:+19725552222@gw1.example.net;unknownparam\r\n".as_bytes())
.unwrap();
assert_eq!(
val.sip_uri().unwrap().user_info().unwrap().value,
"+19725552222"
);
assert_eq!(val.sip_uri().unwrap().hostport.host, "gw1.example.net");
assert_eq!(inp, ";unknownparam\r\n".as_bytes());
let (inp, val) =
Contact::take_value("<sip:+19725552222@gw1.example.net;unknownparam>\r\n".as_bytes())
.unwrap();
assert_eq!(
val.sip_uri().unwrap().user_info().unwrap().value,
"+19725552222"
);
assert_eq!(val.sip_uri().unwrap().hostport.host, "gw1.example.net");
assert_eq!(
val.sip_uri()
.unwrap()
.params()
.unwrap()
.get(&"unknownparam"),
Some(&None)
);
assert_eq!(inp, "\r\n".as_bytes());
let (inp, val) =
Contact::take_value("<http://www.example.com/sounds/moo.wav> ;param\r\n".as_bytes())
.unwrap();
assert_eq!(
val.tags().unwrap()[&HeaderTagType::AbsoluteURI],
"http://www.example.com/sounds/moo.wav".as_bytes()
);
assert_eq!(val.vstr, "<http://www.example.com/sounds/moo.wav>");
assert_eq!(inp, ";param\r\n".as_bytes());
}
}