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\nVia: localhost\r\n\r\n")
+ MESSAGE\r\nDate:Sat, 13 Nov 2010 23:29:00 \
+ GMT\r\nError-Info:<sip:not-in-service-recording@atlanta.com>\r\nVia: \
+ localhost\r\n\r\n")
});
let finished = request.and_then(|(socket, _request)| {
Language, AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse,
Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, ContactTarget,
Contact, DispositionType, Handling, DispositionParam, ContentCoding, Day, Month, Date,
- Time, DateTime};
+ Time, DateTime, ErrorUri};
fn is_mark(c: u8) -> bool {
c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' ||
tag!(b"Date:"),
date_time));
+named!(error_uri<ErrorUri>, tuple!(
+ delimited!(
+ tag!(b"<"),
+ absolute_uri,
+ tag!(b">")
+ ),
+ many0!(preceded!(
+ tag!(b";"),
+ generic_param))));
+
+named!(error_info_header<Vec<ErrorUri>>, preceded!(
+ tag!(b"Error-Info:"),
+ separated_nonempty_list!(
+ tag!(","),
+ error_uri)));
+
named!(pub header<Header>, alt!(
// RFC 3261 Headers
accept_header => { |a| Header::Accept(a) } |
content_length_header => { |l| Header::ContentLength(l) } |
content_type_header => { |t| Header::ContentType(t) } |
cseq_header => { |(c, m)| Header::CSeq(c, m) } |
- date_header => { |d| Header::Date(d) }
+ date_header => { |d| Header::Date(d) } |
+ error_info_header => { |e| Header::ErrorInfo(e) }
));
pub type DateTime = (Day, Date, Time);
+pub type ErrorUri = (AbsoluteUri, Vec<GenericParam>);
+
#[derive(Debug)]
pub enum Header {
Accept(Vec<AcceptRange>),
ContentType(MediaType),
CSeq(u32, Method),
Date(DateTime),
+ ErrorInfo(Vec<ErrorUri>),
From(Uri),
To(Uri),
Extension { name: String, value: String },