From 325034f41437824e30d248307641ed05bf261e32 Mon Sep 17 00:00:00 2001 From: Richard Whitehouse Date: Sun, 29 Oct 2017 18:25:38 +0000 Subject: [PATCH] Support From header --- src/codec.rs | 3 ++- src/parser.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++----- src/types.rs | 14 +++++++++--- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/codec.rs b/src/codec.rs index 4c9a348..8a17c2f 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -437,7 +437,8 @@ mod tests { en-gb\r\nContent-Length:0\r\nContent-Type:text/plain\r\nCSeq:1 \ MESSAGE\r\nDate:Sat, 13 Nov 2010 23:29:00 \ GMT\r\nError-Info:\r\nExpires:30\r\nVia: localhost\r\n\r\n") + com>\r\nExpires:30\r\nFrom:sip:+12125551212@server.phone2net.com;\ + tag=887s\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 6bcb573..7216409 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -14,9 +14,9 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH Header, MediaMainType, MediaType, MediaFullType, MediaParameter, MediaRange, GenericParam, AcceptParam, AcceptRange, Coding, Encoding, LanguageTag, LanguageRange, Language, AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse, - Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, ContactTarget, + Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, Target, Contact, DispositionType, Handling, DispositionParam, ContentCoding, Day, Month, Date, - Time, DateTime, ErrorUri}; + Time, DateTime, ErrorUri, FromParam, From}; fn is_mark(c: u8) -> bool { c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' || @@ -311,6 +311,22 @@ named!(sips_uri<&[u8], _SipUri>, preceded!( opt!(uri_headers) ))); +type _SipUriNp = (Option, HostPort); + +named!(sip_uri_np<&[u8], _SipUriNp>, preceded!( + tag!("sip:"), + tuple!( + opt!(userinfo), + hostport + ))); + +named!(sips_uri_np<&[u8], _SipUriNp>, preceded!( + tag!("sips:"), + tuple!( + opt!(userinfo), + hostport + ))); + fn is_scheme_unreserved(c: u8) -> bool { nom::is_alphanumeric(c) || c == b'+' || c == b'-' || c == b'.' } @@ -410,6 +426,23 @@ named!(uri<&[u8], Uri>, alt!( path: p } } )); +// Variant without URI parameters or header parameters +named!(uri_np<&[u8], Uri>, alt!( + sip_uri_np => { |(u, hp)| Uri::Sip(SipUri { + user_info: u, + host_port: hp, + params: vec![], + headers: None }) } | + sips_uri_np => { |(u, hp)| Uri::Sips(SipUri { + user_info: u, + host_port: hp, + params: vec![], + headers: None }) } | + absolute_uri => { |(s, p)| Uri::Generic { + scheme: s, + path: p } } +)); + named!(sip_version<&[u8], Version>, preceded!( tag!("SIP/"), dbg_dmp!(separated_pair!( @@ -771,10 +804,15 @@ named!(contact_param, alt!( expires => {|e| ContactParam::Expires(e) } | generic_param => {|g| ContactParam::Generic(g) })); -named!(contact_target<(ContactTarget, Vec)>, tuple!( +named!(target, alt!( - name_addr => { |(n, u)| ContactTarget::Name(n, u) } | - uri => { |u| ContactTarget::Uri(u) }), + name_addr => { |(n, u)| Target::Name(n, u) } | +// With this target variant, parameters conflict - so they aren't allowed +// See RFC 3261 Section 20.10 + uri_np => { |u| Target::Uri(u) })); + +named!(contact_target<(Target, Vec)>, tuple!( + target, many0!(preceded!( tag!(b";"), contact_param @@ -902,6 +940,18 @@ named!(expires_header, preceded!( tag!(b"Expires:"), number)); +named!(from_param, alt!( + preceded!(tag!("tag="), token) => { |t| FromParam::Tag(t) } | + generic_param => { |g| FromParam::Generic(g) })); + +named!(from_header, preceded!( + alt!(tag!(b"From:") | tag!("f:")), + tuple!( + target, + many0!(preceded!( + tag!(b";"), + from_param))))); + named!(pub header
, alt!( // RFC 3261 Headers accept_header => { |a| Header::Accept(a) } | @@ -922,5 +972,6 @@ named!(pub header
, alt!( cseq_header => { |(c, m)| Header::CSeq(c, m) } | date_header => { |d| Header::Date(d) } | error_info_header => { |e| Header::ErrorInfo(e) } | - expires_header => { |e| Header::Expires(e) } + expires_header => { |e| Header::Expires(e) } | + from_header => { |f| Header::From(f) } )); diff --git a/src/types.rs b/src/types.rs index 6fab135..1afad38 100644 --- a/src/types.rs +++ b/src/types.rs @@ -263,7 +263,7 @@ pub enum ContactParam { } #[derive(Debug)] -pub enum ContactTarget { +pub enum Target { Name(Option>, Uri), Uri(Uri), } @@ -271,7 +271,7 @@ pub enum ContactTarget { #[derive(Debug)] pub enum Contact { Star, - Contact(Vec<(ContactTarget, Vec)>), + Contact(Vec<(Target, Vec)>), } #[derive(Debug)] @@ -333,6 +333,14 @@ pub type DateTime = (Day, Date, Time); pub type ErrorUri = (AbsoluteUri, Vec); +#[derive(Debug)] +pub enum FromParam { + Tag(Vec), + Generic(GenericParam), +} + +pub type From = (Target, Vec); + #[derive(Debug)] pub enum Header { Accept(Vec), @@ -354,7 +362,7 @@ pub enum Header { Date(DateTime), ErrorInfo(Vec), Expires(u32), - From(Uri), + From(From), To(Uri), Extension { name: String, value: String }, } -- 2.34.1