From: Richard Whitehouse Date: Sun, 19 Nov 2017 23:38:55 +0000 (+0000) Subject: Full HCOLON support X-Git-Url: https://git.richardwhiuk.com/?a=commitdiff_plain;h=d5d3f1faec76c63db5274b4d6d8c65fbb4c9f357;p=rust-sip.git Full HCOLON support --- diff --git a/src/codec.rs b/src/codec.rs index 8ade42c..d72bd89 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -480,35 +480,38 @@ mod tests { env_logger::init().unwrap(); let message = - decode_sip_message("MESSAGE sip:test.com \ - SIP/2.0\r\nAccept:text/plain\r\nAccept-Encoding:\ - *\r\nAccept-Language:en-gb\r\nAlert-Info:\r\nAllow: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:\ + decode_sip_message("MESSAGE sip:test.com SIP/2.0\r\nAccept: \ + text/plain\r\nAccept-Encoding: *\r\nAccept-Language: \ + en-gb\r\nAlert-Info: \ + \r\nAllow: \ + 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\nContact:*\r\nContent-Disposition:\ - session\r\nContent-Encoding:gzip\r\nContent-Language:\ - 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\nFrom:sip:+12125551212@server.phone2net.com;\ - tag=887s\r\nIn-Reply-To:70710@saturn.bell-tel.com,17320@saturn.\ - bell-tel.com\r\nMax-Forwards:32\r\nMIME-Version:2.\ - 0\r\nMin-Expires:30\r\nOrganization:Foobar\r\nPriority:\ - normal\r\nProxy-Authenticate:Digest \ - realm=\"atlanta.com\"\r\nProxy-Authorization:Digest \ - username=\"Bob\"\r\nProxy-Require:foo\r\nRecord-Route:\r\nReply-To:\r\nRequire:baz\r\nRetry-After:18000;duration=3600\r\nRoute:\ - \r\nServer:rust-sip \ - tokio\r\nSubject:Foobaz\r\nSupported:rec\r\nTimestamp:1 \ - 2\r\nTo:;tag=287447\r\nUnsupported:\ - 100rel\r\nUser-Agent:rust-sip\r\nVia:SIP/2.0/UDP \ - pc33.atlanta.com;branch=z9hG4bK776asdhds\r\nWarning:370 devnull \ - \"Failure\"\r\nWWW-Authenticate:Digest \ - realm=\"biloxi.com\"\r\nX-Extension:test\r\n\r\n"); + purpose=icon\r\nContact: *\r\nContent-Disposition: \ + session\r\nContent-Encoding: gzip\r\nContent-Language: \ + 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\nFrom: sip:+12125551212@server.phone2net.com; \ + tag=887s\r\nIn-Reply-To: \ + 70710@saturn.bell-tel.com,17320@saturn.bell-tel.\ + com\r\nMax-Forwards: 32\r\nMIME-Version:2.0\r\nMin-Expires: \ + 30\r\nOrganization:Foobar\r\nPriority: \ + normal\r\nProxy-Authenticate: Digest \ + realm=\"atlanta.com\"\r\nProxy-Authorization: Digest \ + username=\"Bob\"\r\nProxy-Require: foo\r\nRecord-Route: \ + \r\nReply-To: \ + \r\nRequire: \ + baz\r\nRetry-After:18000;duration=3600\r\nRoute: \ + \r\nServer: rust-sip \ + tokio\r\nSubject: Foobaz\r\nSupported: rec\r\nTimestamp: 1 \ + 2\r\nTo: ;\ + tag=287447\r\nUnsupported: 100rel\r\nUser-Agent: \ + rust-sip\r\nVia: SIP/2.0/UDP \ + pc33.atlanta.com;branch=z9hG4bK776asdhds\r\nWarning: 370 devnull \ + \"Failure\"\r\nWWW-Authenticate: Digest \ + realm=\"biloxi.com\"\r\nX-Extension: test\r\n\r\n"); if let Message::Request(request) = message { assert_eq!(request.request_line.0.method, Method::MESSAGE); diff --git a/src/parser.rs b/src/parser.rs index 06fb0d6..81a9131 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -498,6 +498,29 @@ named!(pub top_line, alt!( /// Headers +fn is_spacetab(c: u8) -> bool { + c == b' ' || c == b'\t' +} + +fn is_whitespace(c: u8) -> bool { + is_spacetab(c) +} + +named!(spacetab, take_1!(is_spacetab)); + +named!(crlf, tag!(b"\r\n")); + +named!(lws<(Option<(Vec, &[u8])>, Vec)>, pair!( + opt!(pair!(many0!(take_1!(is_whitespace)), crlf)), + many1!(take_1!(is_whitespace)))); + +named!(sws, &[u8])>, Vec)>>, opt!(lws)); + +named!(hcolon, delimited!( + many0!(spacetab), + tag!(b":"), + sws)); + // Accept Header named!(media_main_type, alt!( @@ -581,7 +604,7 @@ named!(accept_range, tuple!( accept_param)))); named!(accept_header>, preceded!( - tag!(b"Accept:"), + terminated!(tag!(b"Accept"), hcolon), separated_nonempty_list!( tag!(b","), accept_range))); @@ -598,7 +621,7 @@ named!(encoding, tuple!( accept_param)))); named!(accept_encoding_header>, preceded!( - tag!(b"Accept-Encoding:"), + terminated!(tag!(b"Accept-Encoding"), hcolon), separated_nonempty_list!( tag!(b","), encoding))); @@ -620,7 +643,7 @@ named!(language, tuple!( accept_param)))); named!(accept_language_header>, preceded!( - tag!(b"Accept-Language:"), + terminated!(tag!(b"Accept-Language"), hcolon), separated_nonempty_list!( tag!(b","), language))); @@ -634,13 +657,13 @@ named!(alert_param, tuple!( many0!(generic_param))); named!(alert_info_header>, preceded!( - tag!(b"Alert-Info:"), + terminated!(tag!(b"Alert-Info"), hcolon), separated_nonempty_list!( tag!(b","), alert_param))); named!(allow_header>, preceded!( - tag!(b"Allow:"), + terminated!(tag!(b"Allow"), hcolon), separated_nonempty_list!( tag!(b","), method))); @@ -685,7 +708,7 @@ named!(ainfo, alt!( nonce_count => { |n| AuthenticationInfo::NonceCount(n) })); named!(authentication_info_header>, preceded!( - tag!(b"Authentication-Info:"), + terminated!(tag!(b"Authentication-Info"), hcolon), separated_nonempty_list!( tag!(b","), ainfo))); @@ -754,7 +777,7 @@ named!(credentials, alt!( other_response => { |(s,p)| Credentials::Other(s, p) })); named!(authorization_header, preceded!( - tag!(b"Authorization:"), + terminated!(tag!(b"Authorization"), hcolon), credentials)); named!(call_id, tuple!( @@ -764,7 +787,7 @@ named!(call_id, tuple!( word)))); named!(call_id_header, preceded!( - alt!(tag!(b"Call-ID:") | tag!(b"i")), + terminated!(alt!(tag!(b"Call-ID") | tag!(b"i")), hcolon), call_id)); named!(purpose, alt!( @@ -790,7 +813,7 @@ named!(info, tuple!( info_param)))); named!(call_info_header>, preceded!( - tag!(b"Call-Info:"), + terminated!(tag!(b"Call-Info"), hcolon), separated_nonempty_list!( tag!(","), info))); @@ -830,7 +853,7 @@ named!(contact_target<(Target, Vec)>, tuple!( )))); named!(contact_header, preceded!( - alt!(tag!(b"Contact:") | tag!(b"m")), + terminated!(alt!(tag!(b"Contact") | tag!(b"m")), hcolon), alt!( tag!(b"*") => { |_| Contact::Star } | separated_nonempty_list!( @@ -855,7 +878,7 @@ named!(disp_param, alt!( generic_param => { |g| DispositionParam::Generic(g) })); named!(content_disposition_header<(DispositionType, Vec)>, preceded!( - tag!(b"Content-Disposition:"), + terminated!(tag!(b"Content-Disposition"), hcolon), tuple!( disp_type, many0!(preceded!( @@ -863,27 +886,27 @@ named!(content_disposition_header<(DispositionType, Vec)>, pre disp_param))))); named!(content_encoding_header>, preceded!( - alt!(tag!(b"Content-Encoding:") | tag!(b"e:")), + terminated!(alt!(tag!(b"Content-Encoding") | tag!(b"e")), hcolon), separated_nonempty_list!( tag!(b","), token))); named!(content_language_header>, preceded!( - tag!(b"Content-Language:"), + terminated!(tag!(b"Content-Language"), hcolon), separated_nonempty_list!( tag!(b","), language_tag))); named!(content_length_header, preceded!( - alt!(tag!(b"Content-Length:") | tag!(b"l:")), + terminated!(alt!(tag!(b"Content-Length") | tag!(b"l")), hcolon), number)); named!(content_type_header, preceded!( - alt!(tag!(b"Content-Type:") | tag!(b"c:")), + terminated!(alt!(tag!(b"Content-Type") | tag!(b"c")), hcolon), media_type)); named!(cseq_header<(u32, Method)>, preceded!( - tag!(b"CSeq:"), + terminated!(tag!(b"CSeq"), hcolon), separated_pair!( number, tag!(" "), @@ -928,7 +951,7 @@ named!(date_time, tuple!( terminated!(time, tag!(b" GMT")))); named!(date_header, preceded!( - tag!(b"Date:"), + terminated!(tag!(b"Date"), hcolon), date_time)); named!(error_uri, tuple!( @@ -942,13 +965,13 @@ named!(error_uri, tuple!( generic_param)))); named!(error_info_header>, preceded!( - tag!(b"Error-Info:"), + terminated!(tag!(b"Error-Info"), hcolon), separated_nonempty_list!( tag!(","), error_uri))); named!(expires_header, preceded!( - tag!(b"Expires:"), + terminated!(tag!(b"Expires"), hcolon), number)); named!(from_param, alt!( @@ -956,7 +979,7 @@ named!(from_param, alt!( generic_param => { |g| FromParam::Generic(g) })); named!(from_header, preceded!( - alt!(tag!(b"From:") | tag!("f:")), + terminated!(alt!(tag!(b"From") | tag!("f")), hcolon), tuple!( target, many0!(preceded!( @@ -964,32 +987,32 @@ named!(from_header, preceded!( from_param))))); named!(in_reply_to_header>, preceded!( - tag!(b"In-Reply-To:"), + terminated!(tag!(b"In-Reply-To"), hcolon), separated_nonempty_list!( tag!(","), call_id))); named!(max_forwards_header, preceded!( - tag!(b"Max-Forwards:"), + terminated!(tag!(b"Max-Forwards"), hcolon), number)); named!(mime_version_header<(u32, u32)>, preceded!( - tag!(b"MIME-Version:"), + terminated!(tag!(b"MIME-Version"), hcolon), separated_pair!( number, tag!(b"."), number))); named!(min_expires_header, preceded!( - tag!(b"Min-Expires:"), + terminated!(tag!(b"Min-Expires"), hcolon), number)); named!(organization_header>, preceded!( - tag!(b"Organization:"), + terminated!(tag!(b"Organization"), hcolon), word)); named!(priority_header, preceded!( - tag!(b"Priority:"), + terminated!(tag!(b"Priority"), hcolon), alt!( tag!(b"emergency") => { |_| Priority::Emergency } | tag!(b"urgent") => { |_| Priority::Urgent } | @@ -1038,15 +1061,15 @@ named!(challenge, alt!( other_challenge => { |(s, p)| Challenge::Other(s, p) })); named!(proxy_authenticate_header, preceded!( - tag!(b"Proxy-Authenticate:"), + terminated!(tag!(b"Proxy-Authenticate"), hcolon), challenge)); named!(proxy_authorization_header, preceded!( - tag!(b"Proxy-Authorization:"), + terminated!(tag!(b"Proxy-Authorization"), hcolon), credentials)); named!(proxy_require_header>, preceded!( - tag!(b"Proxy-Require:"), + terminated!(tag!(b"Proxy-Require"), hcolon), separated_nonempty_list!( tag!(b","), token))); @@ -1058,7 +1081,7 @@ named!(route, pair!( generic_param)))); named!(record_route_header>, preceded!( - tag!(b"Record-Route:"), + terminated!(tag!(b"Record-Route"), hcolon), separated_nonempty_list!( tag!(b","), route))); @@ -1070,13 +1093,13 @@ named!(reply_to, pair!( generic_param)))); named!(reply_to_header>, preceded!( - tag!(b"Reply-To:"), + terminated!(tag!(b"Reply-To"), hcolon), separated_nonempty_list!( tag!(b","), reply_to))); named!(require_header>, preceded!( - tag!(b"Require:"), + terminated!(tag!(b"Require"), hcolon), separated_nonempty_list!( tag!(b","), token))); @@ -1086,7 +1109,7 @@ named!(retry_after_param, alt!( generic_param => { |g| RetryAfterParam::Generic(g) })); named!(retry_after_header, preceded!( - tag!(b"Retry-After:"), + terminated!(tag!(b"Retry-After"), hcolon), pair!( number, many0!(preceded!( @@ -1095,7 +1118,7 @@ named!(retry_after_header, preceded!( ))))); named!(route_header>, preceded!( - tag!(b"Route:"), + terminated!(tag!(b"Route"), hcolon), separated_nonempty_list!( tag!(b","), route))); @@ -1107,17 +1130,17 @@ named!(server, pair!( token)))); named!(server_header>, preceded!( - tag!(b"Server:"), + terminated!(tag!(b"Server"), hcolon), separated_nonempty_list!( tag!(b" "), server))); named!(subject_header>, preceded!( - alt!(tag!(b"Subject:") | tag!(b"s")), + terminated!(alt!(tag!(b"Subject") | tag!(b"s")), hcolon), word)); named!(supported_header>, preceded!( - alt!(tag!(b"Supported:") | tag!(b"k")), + terminated!(alt!(tag!(b"Supported") | tag!(b"k")), hcolon), separated_nonempty_list!( tag!(b","), token))); @@ -1125,7 +1148,7 @@ named!(supported_header>, preceded!( use self::float as delay; named!(timestamp_header>, preceded!( - tag!(b"Timestamp:"), + terminated!(tag!(b"Timestamp"), hcolon), separated_nonempty_list!( tag!(b" "), delay))); @@ -1135,7 +1158,7 @@ named!(to_param, alt!( generic_param => { |g| ToParam::Generic(g) })); named!(to_header, preceded!( - alt!(tag!(b"To:") | tag!("t:")), + terminated!(alt!(tag!(b"To") | tag!("t")), hcolon), tuple!( target, many0!(preceded!( @@ -1143,13 +1166,13 @@ named!(to_header, preceded!( to_param))))); named!(unsupported_header>, preceded!( - tag!(b"Unsupported:"), + terminated!(tag!(b"Unsupported"), hcolon), separated_nonempty_list!( tag!(b","), token))); named!(user_agent_header>, preceded!( - tag!(b"User-Agent:"), + terminated!(tag!(b"User-Agent"), hcolon), separated_nonempty_list!( tag!(b" "), server))); @@ -1194,7 +1217,7 @@ named!(via, tuple!( via_param)))); named!(via_header>, preceded!( - alt!(tag!(b"Via:") | tag!("v:")), + terminated!(alt!(tag!(b"Via") | tag!(b"v")), hcolon), separated_nonempty_list!( tag!(b","), via))); @@ -1209,18 +1232,18 @@ named!(warning, tuple!( quoted_string)); named!(warning_header>, preceded!( - tag!(b"Warning:"), + terminated!(tag!(b"Warning"), hcolon), separated_nonempty_list!( tag!(b","), warning))); named!(www_authenticate_header, preceded!( - tag!(b"WWW-Authenticate:"), + terminated!(tag!(b"WWW-Authenticate"), hcolon), challenge)); named!(extension_header<(Vec, Vec)>, separated_pair!( token, - tag!(":"), + hcolon, word)); named!(pub header
, alt!(