Support Call-ID header
authorRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 14:10:11 +0000 (14:10 +0000)
committerRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 14:10:11 +0000 (14:10 +0000)
src/codec.rs
src/parser.rs
src/types.rs

index a30485d226c82f59f8a53e9110006f9d06ff9efc..a46ec3c158c804a4712d5719a96b3f90d67fff68 100644 (file)
@@ -430,7 +430,8 @@ mod tests {
                            SIP/2.0\r\nAccept:text/plain\r\nAccept-Encoding:*\r\nAccept-Language:\
                            en-gb\r\nAlert-Info:<http://www.example.com/sounds/moo.wav>\r\nAllow:\
                            MESSAGE\r\nAuthentication-Info:qop=auth\r\nAuthorization:Digest \
-                           username=\"Alice\"\r\nVia: localhost\r\n\r\n")
+                           username=\"Alice\"\r\nCall-ID:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.\
+                           bar.com\r\nVia: localhost\r\n\r\n")
         });
 
         let finished = request.and_then(|(socket, _request)| {
index 4c8c03123f2b778cf97e652ffa6b5b81ffd7fbc6..e373b5355581beddeef2c87c351b3c16a9884c0c 100644 (file)
@@ -13,7 +13,7 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH
             Scheme, Method, Transport, UserParam, Version, RequestLine, StatusLine, TopLine,
             Header, MediaType, MediaFullType, MediaParameter, MediaRange, GenericParam,
             AcceptParam, AcceptRange, Coding, Encoding, LanguageRange, Language, AlertParam, Qop,
-            AuthenticationInfo, AuthParam, Algorithm, DigestResponse, Credentials};
+            AuthenticationInfo, AuthParam, Algorithm, DigestResponse, Credentials, CallId};
 
 fn is_mark(c: u8) -> bool {
     c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' ||
@@ -79,11 +79,18 @@ fn is_token(c: u8) -> bool {
     c == b'*' || c == b'_' || c == b'+' || c == b'`' || c == b'\'' || c == b'~'
 }
 
+fn is_word(c: u8) -> bool {
+    is_token(c) || c == b'(' || c == b')' || c == b'<' || c == b'>' || c == b':' ||
+    c == b'\\' || c == b'"' || c == b'/' || c == b'[' || c == b']' ||
+    c == b'?' || c == b'{' || c == b'}'
+}
+
 fn is_lhex_digit(c: u8) -> bool {
     nom::is_digit(c) || (c >= b'a' && c <= b'f')
 }
 
 named!(token<Vec<u8>>, many1!(take_1!(is_token)));
+named!(word<Vec<u8>>, many1!(take_1!(is_word)));
 
 named!(method<Method>, alt!(
 // RFC 3261
@@ -701,6 +708,14 @@ named!(authorization_header<Credentials>, preceded!(
        tag!(b"Authorization:"),
        credentials));
 
+named!(call_id_header<CallId>, preceded!(
+       alt!(tag!(b"Call-ID:") | tag!(b"i")),
+       tuple!(
+               word,
+               opt!(preceded!(
+                       tag!(b"@"),
+                       word)))));
+
 named!(pub header<Header>, alt!(
 // RFC 3261 Headers
        accept_header => { |a| Header::Accept(a) } |
@@ -709,5 +724,6 @@ named!(pub header<Header>, alt!(
        alert_info_header => { |a| Header::AlertInfo(a) } |
        allow_header => { |a| Header::Allow(a) } |
        authentication_info_header => { |a| Header::AuthenticationInfo(a) } |
-       authorization_header => { |a| Header::Authorization(a) }
+       authorization_header => { |a| Header::Authorization(a) } |
+       call_id_header => { |c| Header::CallId(c) }
 ));
index e0e2cf1361f8b02042be987b44f2a435381db1e5..e8c6f0007d1aadf2be7483d799b95341d5f50b94 100644 (file)
@@ -231,6 +231,8 @@ pub enum Credentials {
     Other(Vec<u8>, Vec<AuthParam>),
 }
 
+pub type CallId = (Vec<u8>, Option<Vec<u8>>);
+
 #[derive(Debug)]
 pub enum Header {
     Accept(Vec<AcceptRange>),
@@ -240,6 +242,7 @@ pub enum Header {
     Allow(Vec<Method>),
     AuthenticationInfo(Vec<AuthenticationInfo>),
     Authorization(Credentials),
+    CallId(CallId),
     From(Uri),
     To(Uri),
     Extension { name: String, value: String },