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)| {
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'\'' ||
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
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) } |
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) }
));
Other(Vec<u8>, Vec<AuthParam>),
}
+pub type CallId = (Vec<u8>, Option<Vec<u8>>);
+
#[derive(Debug)]
pub enum Header {
Accept(Vec<AcceptRange>),
Allow(Vec<Method>),
AuthenticationInfo(Vec<AuthenticationInfo>),
Authorization(Credentials),
+ CallId(CallId),
From(Uri),
To(Uri),
Extension { name: String, value: String },