Support Content-Type header
authorRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 16:07:12 +0000 (16:07 +0000)
committerRichard Whitehouse <github@richardwhiuk.com>
Sun, 29 Oct 2017 16:07:12 +0000 (16:07 +0000)
src/codec.rs
src/parser.rs
src/types.rs

index 83055e2b877023eb2430091698fb9f82044e6aa3..798b8ef8798d8e20fb3236a857e086448ad7ba11 100644 (file)
@@ -434,7 +434,8 @@ mod tests {
                            bar.com\r\nCall-Info:<http://wwww.example.com/alice/photo.jpg>;\
                            purpose=icon\r\nContact:*\r\nContent-Disposition:\
                            session\r\nContent-Encoding:gzip\r\nContent-Language:\
-                           en-gb\r\nContent-Length:0\r\nVia: localhost\r\n\r\n")
+                           en-gb\r\nContent-Length:0\r\nContent-Type:text/plain\r\nVia: \
+                           localhost\r\n\r\n")
         });
 
         let finished = request.and_then(|(socket, _request)| {
index 556069968710a6c9a45fae3fc525d944029bbc7b..6861c0b03ee1bdab65d1f6078e4d346b77ee3f5a 100644 (file)
@@ -11,9 +11,9 @@ use nom::ErrorKind::Custom;
 use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriHeaders, SipUri,
             AbsoluteUri, Uri, HierarchicalPath, Authority, UriPath, UserInfo, AbsolutePath,
             Scheme, Method, Transport, UserParam, Version, RequestLine, StatusLine, TopLine,
-            Header, MediaType, MediaFullType, MediaParameter, MediaRange, GenericParam,
-            AcceptParam, AcceptRange, Coding, Encoding, LanguageTag, LanguageRange, Language,
-            AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse,
+            Header, MediaMainType, MediaType, MediaFullType, MediaParameter, MediaRange,
+            GenericParam, AcceptParam, AcceptRange, Coding, Encoding, LanguageTag, LanguageRange,
+            Language, AlertParam, Qop, AuthenticationInfo, AuthParam, Algorithm, DigestResponse,
             Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, ContactTarget,
             Contact, DispositionType, Handling, DispositionParam, ContentCoding};
 
@@ -457,18 +457,18 @@ named!(pub top_line<TopLine>, alt!(
 
 // Accept Header
 
-named!(media_type<MediaType>, alt!(
+named!(media_main_type<MediaMainType>, alt!(
 // Discrete Types
-       tag!(b"text") => { |_| MediaType::Text } |
-       tag!(b"image") => { |_| MediaType::Image } |
-       tag!(b"audio") => { |_| MediaType::Audio } |
-       tag!(b"video") => { |_| MediaType::Video } |
-       tag!(b"application") => { |_| MediaType::Application } |
+       tag!(b"text") => { |_| MediaMainType::Text } |
+       tag!(b"image") => { |_| MediaMainType::Image } |
+       tag!(b"audio") => { |_| MediaMainType::Audio } |
+       tag!(b"video") => { |_| MediaMainType::Video } |
+       tag!(b"application") => { |_| MediaMainType::Application } |
 // Composite Types
-       tag!(b"message") => { |_| MediaType::Message } |
-       tag!(b"multipart") => { |_| MediaType::Multipart } |
+       tag!(b"message") => { |_| MediaMainType::Message } |
+       tag!(b"multipart") => { |_| MediaMainType::Multipart } |
 // Extensions
-       token => { |x| MediaType::Extension(x) }));
+       token => { |x| MediaMainType::Extension(x) }));
 
 // We don't bother splitting IANA, IETF and x- token types.
 use self::token as media_subtype;
@@ -505,14 +505,16 @@ named!(media_parameter<MediaParameter>, separated_pair!(
        tag!(b"="),
        media_value));
 
+named!(media_type<MediaType>, separated_pair!(
+       media_main_type,
+       tag!(b"/"),
+       media_subtype));
+
 named!(media_range<MediaRange>, tuple!(
        alt!(
                tag!(b"*/*") => { |_| MediaFullType::All } |
-               terminated!(media_type, tag!(b"/*")) => { |x| MediaFullType::Partial(x) } | /**/
-               separated_pair!(
-                       media_type,
-                       tag!(b"/"),
-                       media_subtype) => { |(t, st)| MediaFullType::Specific(t, st) }),
+               terminated!(media_main_type, tag!(b"/*")) => { |x| MediaFullType::Partial(x) } | /**/
+               media_type => { |(t, st)| MediaFullType::Specific(t, st) }),
        many0!(
                preceded!(tag!(b";"), media_parameter))));
 
@@ -826,6 +828,10 @@ named!(content_length_header<u32>, preceded!(
        alt!(tag!(b"Content-Length:") | tag!(b"l:")),
        number));
 
+named!(content_type_header<MediaType>, preceded!(
+       alt!(tag!(b"Content-Type:") | tag!(b"c:")),
+       media_type));
+
 named!(pub header<Header>, alt!(
 // RFC 3261 Headers
        accept_header => { |a| Header::Accept(a) } |
@@ -841,5 +847,6 @@ named!(pub header<Header>, alt!(
        content_disposition_header => { |(t, p)| Header::ContentDisposition(t, p) } |
        content_encoding_header => { |e| Header::ContentEncoding(e) } |
        content_language_header => { |l| Header::ContentLanguage(l) } |
-       content_length_header => { |l| Header::ContentLength(l) }
+       content_length_header => { |l| Header::ContentLength(l) } |
+       content_type_header => { |t| Header::ContentType(t) }
 ));
index b868b629378941b541728088c39e16b18ac6f2bf..012cffb324a5a33969641d888e54c488098eb549 100644 (file)
@@ -135,7 +135,7 @@ pub enum TopLine {
 }
 
 #[derive(Debug)]
-pub enum MediaType {
+pub enum MediaMainType {
     Text,
     Image,
     Audio,
@@ -146,11 +146,13 @@ pub enum MediaType {
     Extension(Vec<u8>),
 }
 
+pub type MediaType = (MediaMainType, Vec<u8>);
+
 #[derive(Debug)]
 pub enum MediaFullType {
     All,
-    Partial(MediaType),
-    Specific(MediaType, Vec<u8>),
+    Partial(MediaMainType),
+    Specific(MediaMainType, Vec<u8>),
 }
 
 pub type MediaParameter = (Vec<u8>, Vec<u8>);
@@ -312,6 +314,7 @@ pub enum Header {
     ContentEncoding(Vec<ContentCoding>),
     ContentLanguage(Vec<LanguageTag>),
     ContentLength(u32),
+    ContentType(MediaType),
     From(Uri),
     To(Uri),
     Extension { name: String, value: String },