Support Retry-After header
authorRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 21:52:25 +0000 (21:52 +0000)
committerRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 21:52:25 +0000 (21:52 +0000)
src/codec.rs
src/parser.rs
src/types.rs

index 28be0fa414490c4a209e6ba745ef7e98b1e4a19b..c9800300d4afa37bf05d4661959477e1f3f0508b 100644 (file)
@@ -443,8 +443,8 @@ mod tests {
                            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:<sip:server10.\
-                           biloxi.com;lr>\r\nReply-To:<sip:bob@biloxi.com>\r\nRequire:baz\r\nVia: \
-                           localhost\r\n\r\n")
+                           biloxi.com;lr>\r\nReply-To:<sip:bob@biloxi.com>\r\nRequire:\
+                           baz\r\nRetry-After:18000;duration=3600\r\nVia: localhost\r\n\r\n")
         });
 
         let finished = request.and_then(|(socket, _request)| {
index 4d419d449c3a440963c4658bb3dc80754b8f07c9..3891e471b2c000eeff87e00790681378643dbfc6 100644 (file)
@@ -17,7 +17,7 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH
             Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, Target,
             Contact, DispositionType, Handling, DispositionParam, ContentCoding, Day, Month, Date,
             Time, DateTime, ErrorUri, FromParam, From, Priority, Domain, DigestChallenge,
-            Challenge, OptionTag, Route, ReplyTo};
+            Challenge, OptionTag, Route, ReplyTo, RetryAfterParam, RetryAfter };
 
 fn is_mark(c: u8) -> bool {
     c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' ||
@@ -1073,6 +1073,19 @@ named!(require_header<Vec<OptionTag>>, preceded!(
                tag!(b","),
                token)));
 
+named!(retry_after_param<RetryAfterParam>, alt!(
+       preceded!(tag!(b"duration="), number) => { |d| RetryAfterParam::Duration(d) } |
+       generic_param => { |g| RetryAfterParam::Generic(g) }));
+
+named!(retry_after_header<RetryAfter>, preceded!(
+       tag!(b"Retry-After:"),
+       pair!(
+               number,
+               many0!(preceded!(
+                       tag!(b";"),
+                       retry_after_param
+               )))));
+
 named!(pub header<Header>, alt!(
 // RFC 3261 Headers
        accept_header => { |a| Header::Accept(a) } |
@@ -1106,5 +1119,6 @@ named!(pub header<Header>, alt!(
        proxy_require_header => { |p| Header::ProxyRequire(p) } |
        record_route_header => { |r| Header::RecordRoute(r) } |
        reply_to_header => { |r| Header::ReplyTo(r) } |
-       require_header => { |r| Header::Require(r) }
+       require_header => { |r| Header::Require(r) } |
+       retry_after_header => { |r| Header::RetryAfter(r) }
 ));
index a40963960edf41f01604967175375599fab3a8d2..826f6608136df6485b408f751fdd7faa83449e5f 100644 (file)
@@ -379,6 +379,14 @@ pub type Route = (NameAddr, Vec<GenericParam>);
 
 pub type ReplyTo = (Target, Vec<GenericParam>);
 
+#[derive(Debug)]
+pub enum RetryAfterParam {
+    Duration(u32),
+    Generic(GenericParam),
+}
+
+pub type RetryAfter = (u32, Vec<RetryAfterParam>);
+
 #[derive(Debug)]
 pub enum Header {
     Accept(Vec<AcceptRange>),
@@ -413,6 +421,7 @@ pub enum Header {
     RecordRoute(Vec<Route>),
     ReplyTo(Vec<ReplyTo>),
     Require(Vec<OptionTag>),
+    RetryAfter(RetryAfter),
     To(Uri),
     Extension { name: String, value: String },
 }