[Xfce4-commits] <postler:master> Refactor content type parsing and handle inner boundaries

Christian Dywan noreply at xfce.org
Thu Jul 29 12:26:03 CEST 2010


Updating branch refs/heads/master
         to 459b807035f31ada628516d90e361a49174a57fc (commit)
       from 48e82afe7ec5f175fb10105db5b4489a39208ebd (commit)

commit 459b807035f31ada628516d90e361a49174a57fc
Author: Christian Dywan <christian at twotoasts.de>
Date:   Mon Jul 19 22:42:19 2010 +0200

    Refactor content type parsing and handle inner boundaries
    
    For now, nested message parts are simply appended.
    
    Also watch out for '; ' as opposed to ';' at line endings.

 postler/postler-content.vala |  121 ++++++++++++++++++++++++------------------
 1 files changed, 70 insertions(+), 51 deletions(-)

diff --git a/postler/postler-content.vala b/postler/postler-content.vala
index f911131..172daa0 100644
--- a/postler/postler-content.vala
+++ b/postler/postler-content.vala
@@ -366,6 +366,33 @@ public class Postler.Content : WebKit.WebView {
         return true;
     }
 
+    static void parse_content_type (string? content_type, ref string charset,
+        ref string boundary, ref string mime_type) {
+
+        if (content_type == null)
+            return;
+
+        string[] parts = content_type.split_set ("; ");
+        string filename = null;
+        foreach (var part in parts) {
+            if (part.has_prefix ("charset="))
+                charset = part.substring (8, part.length - 8);
+            else if (part.has_prefix ("name="))
+                filename = part.substring (5, part.length - 5);
+            else if (part.has_prefix ("boundary="))
+                boundary = part.substring (9, part.length - 9);
+            else if (part != "" && !part.contains ("="))
+                mime_type = ascii_strdown (part);
+        }
+
+        if (mime_type == "application/octet-stream" && filename != null) {
+            filename = filename.replace ("\"", " ").strip ();
+            uchar[] data = {};
+            bool uncertain;
+            mime_type = g_content_type_guess (filename, data, out uncertain);
+        }
+    }
+
     public bool display (string location) {
         last_location = location;
         subject = _("(No subject)");
@@ -397,17 +424,9 @@ public class Postler.Content : WebKit.WebView {
                     body.append (line + "\n");
                 }
 
-                if (content_type != null) {
-                    parts = content_type.split_set ("; ");
-                    foreach (var part in parts) {
-                        if (part.has_prefix ("charset="))
-                            charset = part.substring (8, part.length - 8);
-                        else if (part != "" && !part.contains ("="))
-                            mime_type = ascii_strdown (part);
-                    }
-                }
-                if (charset == null)
-                    charset = default_charset;
+                string? boundary = null;
+                parse_content_type (content_type, ref charset, ref boundary,
+                                    ref mime_type);
 
                 /* FIXME view_source_mode requires WebKitGTK+ 1.1.something */
                 set_view_source_mode (true);
@@ -431,7 +450,9 @@ public class Postler.Content : WebKit.WebView {
             while ((line = stream.read_line (null, null)) != null) {
                 if (line == "")
                     break;
-                if (line.has_suffix (",") || line.has_suffix (";")) {
+                if (line.has_suffix (",")
+                 || line.has_suffix (";")
+                 || line.has_suffix ("; ")) {
                     previous_line += line;
                     continue;
                 }
@@ -515,29 +536,8 @@ public class Postler.Content : WebKit.WebView {
             if (reply != "")
                 reply = linkify_address (reply, arguments);
 
-            string boundary = null;
-            if (content_type != null) {
-                parts = content_type.split_set ("; ");
-                string filename = null;
-                foreach (var part in parts) {
-                    if (part.has_prefix ("charset="))
-                        charset = part.substring (8, part.length - 8);
-                    else if (part.has_prefix ("name="))
-                        filename = part.substring (5, part.length - 5);
-                    else if (part.has_prefix ("boundary="))
-                        boundary = part.substring (9, part.length - 9);
-                    else if (part != "" && !part.contains ("="))
-                        mime_type = ascii_strdown (part);
-                }
-
-                if (mime_type == "application/octet-stream" && filename != null) {
-                    filename = filename.replace ("\"", " ").strip ();
-                    uchar[] data = {};
-                    bool uncertain;
-                    mime_type = g_content_type_guess (filename,
-                        data, out uncertain);
-                }
-            }
+            string? boundary = null;
+            parse_content_type (content_type, ref charset, ref boundary, ref mime_type);
 
             uint multipart = mime_type.has_prefix ("multipart/") ? 1 : 0;
             if (multipart > 0 && boundary != null)
@@ -564,10 +564,20 @@ public class Postler.Content : WebKit.WebView {
             bool plain_text = mime_type == "text/plain";
             bool in_quote = false;
             bool in_signature = false;
+            string inner_boundary = "";
             while ((line = stream.read_line (null, null)) != null) {
                 if (multipart > 0) {
                     if (line.has_prefix ("--")) {
-                        if (line == "--" + boundary) {
+                        if (line == "--" + inner_boundary) {
+                            body += new GLib.StringBuilder ();
+                            mime_types += "text/plain";
+                            plain_text = true;
+                            body_parts++;
+                            multipart = 2;
+                            continue;
+                        } else if (line == "--" + boundary) {
+                            /* TODO: Merge inner text parts */
+                            inner_boundary = "";
                             body += new GLib.StringBuilder ();
                             mime_types += "text/plain";
                             plain_text = true;
@@ -577,21 +587,30 @@ public class Postler.Content : WebKit.WebView {
                         }
                     }
                     else if (multipart == 2) {
-                        parts = line.split (":", 2);
-                        if (parts[0] != null) {
-                            string field = ascii_strdown (parts[0]);
-                            if (field == "content-type") {
-                                string ctype = parts[1].strip ();
-                                parts = ctype.split_set ("; ");
-                                mime_types[body_parts] = ascii_strdown (parts[0].strip ());
-                                if (mime_types[body_parts] != "text/plain")
-                                    plain_text = false;
-                                continue;
-                            }
-                            else if (field == "content-transfer-encoding") {
-                                /* TODO: Handle encoding */
-                                continue;
-                            }
+                        /* Content-Type can span over multiple lines */
+                        if (mime_types[body_parts].has_suffix (";"))
+                            parts = { "content-type",
+                                      mime_types[body_parts] + line };
+                        else
+                            parts = line.split (":", 2);
+
+                        string field = ascii_strdown (parts[0] ?? "");
+                        if (field == "content-type") {
+                            string cset = default_charset;
+                            string mtype = "text/plain";
+                            parse_content_type (parts[1].strip (), ref cset,
+                                ref inner_boundary, ref mtype);
+
+                            if (line.chomp ().has_suffix (";"))
+                                mtype += ";";
+                            if (mtype != "text/plain")
+                                plain_text = false;
+                            mime_types[body_parts] = mtype;
+                            continue;
+                        }
+                        else if (field == "content-transfer-encoding") {
+                            /* TODO: Handle encoding */
+                            continue;
                         }
                     }
                     else if (multipart == 1)



More information about the Xfce4-commits mailing list