Support Proxy-Authenticate header
authorRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 20:06:30 +0000 (20:06 +0000)
committerRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 20:06:30 +0000 (20:06 +0000)
src/codec.rs
src/parser.rs
src/types.rs

index 31f9a4985c2baec0de58a91e395f72b430f2683b..4b292a844ac99628c50249a3bbdd5856a442f4ca 100644 (file)
@@ -440,7 +440,8 @@ mod tests {
                            com>\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\nVia: localhost\r\n\r\n")
+                           30\r\nOrganization:Foobar\r\nPriority:normal\r\nProxy-Authenticate:\
+                           Digest realm=\"atlanta.com\"\r\nVia: localhost\r\n\r\n")
         });
 
         let finished = request.and_then(|(socket, _request)| {
index 59aed8e06c48ab4a57412740f4d90368b5860850..ac051a71b51422769807351e68a2e42d319ad0cb 100644 (file)
@@ -16,7 +16,8 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH
             Language, AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse,
             Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, Target,
             Contact, DispositionType, Handling, DispositionParam, ContentCoding, Day, Month, Date,
-            Time, DateTime, ErrorUri, FromParam, From, Priority};
+            Time, DateTime, ErrorUri, FromParam, From, Priority, Domain, DigestChallenge,
+            Challenge};
 
 fn is_mark(c: u8) -> bool {
     c == b'-' || c == b'_' || c == b'.' || c == b'!' || c == b'~' || c == b'*' || c == b'\'' ||
@@ -988,6 +989,50 @@ named!(priority_header<Priority>, preceded!(
                tag!(b"non-urgent") => { |_| Priority::NonUrgent } |
                token => { |t| Priority::Other(t) })));
 
+named!(domain<Vec<Domain>>, delimited!(
+       tag!(b"domain=\""),
+       separated_nonempty_list!(
+               tag!(" "),
+               alt!(
+                       absolute_uri => { |u| Domain::Uri(u) } |
+                       abs_path => { |p| Domain::Path(p) }
+               )),
+       tag!(b"\"")));
+
+named!(boolean<bool>, alt!(
+       tag!(b"true") => { |_| true } |
+       tag!(b"false") => { |_| false }));
+
+named!(stale<bool>, preceded!(
+       tag!(b"stale="),
+       boolean));
+
+named!(qop_options<Vec<Qop>>, delimited!(
+       tag!(b"qop=\""),
+       separated_nonempty_list!(
+               tag!(b","),
+               qop_value),
+       tag!(b"\"")));
+
+named!(digest_challenge<Vec<DigestChallenge>>, many1!(alt!(
+       realm => { |r| DigestChallenge::Realm(r) } |
+       domain => { |d| DigestChallenge::Domain(d) } |
+       nonce => { |n| DigestChallenge::Nonce(n) } |
+       opaque => { |o| DigestChallenge::Opaque(o) } |
+       stale => { |s| DigestChallenge::Stale(s) } |
+       qop_options => { |q| DigestChallenge::QopOptions(q) } |
+       auth_param => { |(k, v)| DigestChallenge::AuthParam(k, v) })));
+
+use self::other_response as other_challenge;
+
+named!(challenge<Challenge>, alt!(
+       preceded!(tag!(b"Digest "), digest_challenge) => { |d| Challenge::Digest(d) } |
+       other_challenge => { |(s, p)| Challenge::Other(s, p) }));
+
+named!(proxy_authenticate_header<Challenge>, preceded!(
+       tag!(b"Proxy-Authenticate:"),
+       challenge));
+
 named!(pub header<Header>, alt!(
 // RFC 3261 Headers
        accept_header => { |a| Header::Accept(a) } |
@@ -1015,5 +1060,6 @@ named!(pub header<Header>, alt!(
        mime_version_header => { |(m, v)| Header::MimeVersion(m, v) } |
        min_expires_header => { |m| Header::MinExpires(m) } |
        organization_header => { |o| Header::Organization(o) } |
-       priority_header => { |p| Header::Priority(p) }
+       priority_header => { |p| Header::Priority(p) } |
+       proxy_authenticate_header => { |p| Header::ProxyAuthenticate(p) }
 ));
index 6a546d202799b05d22d165656356f247f792bffc..6a48c4a285dadea07fa628207ad29828e892ccf5 100644 (file)
@@ -343,11 +343,34 @@ pub type From = (Target, Vec<FromParam>);
 
 #[derive(Debug)]
 pub enum Priority {
-       Emergency,
-       Urgent,
-       Normal,
-       NonUrgent,
-       Other(Vec<u8>)
+    Emergency,
+    Urgent,
+    Normal,
+    NonUrgent,
+    Other(Vec<u8>),
+}
+
+#[derive(Debug)]
+pub enum Domain {
+    Uri(AbsoluteUri),
+    Path(AbsolutePath),
+}
+
+#[derive(Debug)]
+pub enum DigestChallenge {
+    Realm(Vec<u8>),
+    Domain(Vec<Domain>),
+    Nonce(Vec<u8>),
+    Opaque(Vec<u8>),
+    Stale(bool),
+    QopOptions(Vec<Qop>),
+    AuthParam(Vec<u8>, Vec<u8>),
+}
+
+#[derive(Debug)]
+pub enum Challenge {
+    Digest(Vec<DigestChallenge>),
+    Other(Vec<u8>, Vec<AuthParam>),
 }
 
 #[derive(Debug)]
@@ -378,6 +401,7 @@ pub enum Header {
     MinExpires(u32),
     Organization(Vec<u8>),
     Priority(Priority),
+    ProxyAuthenticate(Challenge),
     To(Uri),
     Extension { name: String, value: String },
 }