From: Richard Whitehouse Date: Sun, 29 Oct 2017 15:12:32 +0000 (+0000) Subject: Support Contact header X-Git-Url: https://git.richardwhiuk.com/?a=commitdiff_plain;h=2647206b8321cc2470ce81e57fa2ecc38afac32c;p=rust-sip.git Support Contact header --- diff --git a/src/codec.rs b/src/codec.rs index 36eeff7..adce8bc 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -432,7 +432,7 @@ mod tests { MESSAGE\r\nAuthentication-Info:qop=auth\r\nAuthorization:Digest \ username=\"Alice\"\r\nCall-ID:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.\ bar.com\r\nCall-Info:;\ - purpose=icon\r\nVia: localhost\r\n\r\n") + purpose=icon\r\nContact:*\r\nVia: localhost\r\n\r\n") }); let finished = request.and_then(|(socket, _request)| { diff --git a/src/parser.rs b/src/parser.rs index 3e4b202..1e77e48 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -14,7 +14,7 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH Header, MediaType, MediaFullType, MediaParameter, MediaRange, GenericParam, AcceptParam, AcceptRange, Coding, Encoding, LanguageRange, Language, AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse, Credentials, CallId, - Purpose, InfoParam, Info}; + Purpose, InfoParam, Info, NameAddr, ContactParam, ContactTarget, Contact}; fn is_mark(c: u8) -> bool { c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' || @@ -392,7 +392,7 @@ named!(absolute_uri<&[u8], AbsoluteUri>, separated_pair!( opaque_part => { |(b, o)| UriPath::Opaque(b, o) } ))); -named!(request_uri<&[u8], Uri>, alt!( +named!(uri<&[u8], Uri>, alt!( sip_uri => { |(u, hp, p, h)| Uri::Sip(SipUri { user_info: u, host_port: hp, @@ -419,7 +419,7 @@ named!(request_line<&[u8], (Method, Uri, Version)>, tuple!( method, delimited!( tag!(" "), - request_uri, + uri, tag!(" ")), sip_version)); @@ -522,8 +522,10 @@ named!(generic_param, separated_pair!( use nom::float as qvalue; +named!(qparam, preceded!(tag!(b"q="), qvalue)); + named!(accept_param, alt!( - preceded!(tag!(b"q"), qvalue) => { |x| AcceptParam::Qvalue(x) } | + qparam => { |x| AcceptParam::Qvalue(x) } | generic_param => { |x| AcceptParam::Generic(x) })); named!(accept_range, tuple!( @@ -745,6 +747,43 @@ named!(call_info_header>, preceded!( tag!(","), info))); +named!(display_name>, alt!( + token | + quoted_string)); + +named!(name_addr, tuple!( + opt!(display_name), + delimited!( + tag!(b"<"), + uri, + tag!(b">")))); + +named!(expires, preceded!( + tag!(b"expires="), + number)); + +named!(contact_param, alt!( + qparam => {|q| ContactParam::Qvalue(q) } | + expires => {|e| ContactParam::Expires(e) } | + generic_param => {|g| ContactParam::Generic(g) })); + +named!(contact_target<(ContactTarget, Vec)>, tuple!( + alt!( + name_addr => { |(n, u)| ContactTarget::Name(n, u) } | + uri => { |u| ContactTarget::Uri(u) }), + many0!(preceded!( + tag!(b";"), + contact_param + )))); + +named!(contact_header, preceded!( + alt!(tag!(b"Contact:") | tag!(b"m")), + alt!( + tag!(b"*") => { |_| Contact::Star } | + separated_nonempty_list!( + tag!(","), + contact_target) => { |c| Contact::Contact(c) }))); + named!(pub header
, alt!( // RFC 3261 Headers accept_header => { |a| Header::Accept(a) } | @@ -755,5 +794,6 @@ named!(pub header
, alt!( authentication_info_header => { |a| Header::AuthenticationInfo(a) } | authorization_header => { |a| Header::Authorization(a) } | call_id_header => { |c| Header::CallId(c) } | - call_info_header => { |c| Header::CallInfo(c) } + call_info_header => { |c| Header::CallInfo(c) } | + contact_header => { |c| Header::Contact(c) } )); diff --git a/src/types.rs b/src/types.rs index e05f4e4..2278528 100644 --- a/src/types.rs +++ b/src/types.rs @@ -249,6 +249,27 @@ pub enum InfoParam { pub type Info = (AbsoluteUri, Vec); +pub type NameAddr = (Option>, Uri); + +#[derive(Debug)] +pub enum ContactParam { + Qvalue(f32), + Expires(u32), + Generic(GenericParam), +} + +#[derive(Debug)] +pub enum ContactTarget { + Name(Option>, Uri), + Uri(Uri), +} + +#[derive(Debug)] +pub enum Contact { + Star, + Contact(Vec<(ContactTarget, Vec)>), +} + #[derive(Debug)] pub enum Header { Accept(Vec), @@ -260,6 +281,7 @@ pub enum Header { Authorization(Credentials), CallId(CallId), CallInfo(Vec), + Contact(Contact), From(Uri), To(Uri), Extension { name: String, value: String },