Parse transport message headers using MimeKit.
authorDean
Mon, 31 Oct 2016 16:19:52 +0100
changeset 1403 2227d470a0b3
parent 1402 4322d0b8e8ed
child 1404 3ad362c52ad4
Parse transport message headers using MimeKit.
MailItemExtensions.cs
Resources/Credits.rtf
pEpForOutlook.csproj
packages.config
--- a/MailItemExtensions.cs	Mon Oct 31 14:32:21 2016 +0100
+++ b/MailItemExtensions.cs	Mon Oct 31 16:19:52 2016 +0100
@@ -1,5 +1,7 @@
-using pEpCOMServerAdapterLib;
+using MimeKit;
+using pEpCOMServerAdapterLib;
 using System;
+using System.IO;
 using System.Runtime.InteropServices;
 using System.Text;
 using Outlook = Microsoft.Office.Interop.Outlook;
@@ -860,6 +862,52 @@
         }
 
         /// <summary>
+        /// Gets the parsed transport message headers (MIME headers) of the given Outlook mail item.
+        /// This will internally use the MAPI property PidTagTransportMessageHeaders.
+        /// Warning: This can return null.
+        /// </summary>
+        /// <param name="omi">The outlook mail item to process with.</param>
+        /// <returns>The parsed transport message headers, otherwise null.</returns>
+        private static HeaderList GetParsedTransportMessageHeaders(this Outlook.MailItem omi)
+        {
+            string messageHeaders = null;
+            MemoryStream stream = null;
+            MimeParser mimeParser;
+            HeaderList headers = null;
+
+            if (omi != null)
+            {
+                messageHeaders = MapiHelper.GetProperty(omi, MapiProperty.PidTagTransportMessageHeaders, string.Empty) as string;
+
+                if (string.IsNullOrEmpty(messageHeaders) == false)
+                {
+                    // Parse the headers using MimeKit
+                    try
+                    {
+                        stream = new MemoryStream(Encoding.UTF8.GetBytes(messageHeaders));
+                        mimeParser = new MimeParser(stream);
+                        headers = mimeParser.ParseHeaders();
+                    }
+                    catch (Exception e)
+                    {
+                        Log.Error("GetParsedTransportMessageHeaders: Failed to parse MIME headers, " + e.ToString());
+                    }
+                    finally
+                    {
+                        if (stream != null)
+                        {
+                            stream.Close();
+                            stream.Dispose();
+                            stream = null;
+                        }
+                    }
+                }
+            }
+
+            return (headers);
+        }
+
+        /// <summary>
         /// Gets the default value for the given UserProperty or MAPI property.
         /// Warning: The propertyName for a UserProperty or MAPI property must never be the same.
         /// </summary>
@@ -938,7 +986,7 @@
             bool success = false;
             object propertyValue;
             object outValue = defaultValue;
-            string messageHeaders = null;
+            HeaderList messageHeaders;
 
             try
             {
@@ -959,12 +1007,19 @@
                                 }
                                 else
                                 {
-                                    messageHeaders = MapiHelper.GetProperty(omi, MapiProperty.PidTagTransportMessageHeaders) as string;
-
-                                    if ((string.IsNullOrEmpty(messageHeaders) == false) &&
-                                        (messageHeaders.ToUpperInvariant().Contains(("pEp-auto-consume: yes").ToUpperInvariant())))
+                                    // As a backup search the original internet message headers
+                                    messageHeaders = omi.GetParsedTransportMessageHeaders();
+                                    if (messageHeaders != null)
                                     {
-                                        outValue = "yes";
+                                        foreach (Header header in messageHeaders)
+                                        {
+                                            if ((header.Field != null) &&
+                                                (header.Value != null) &&
+                                                (string.Equals(header.Field.Trim(), PEPMessage.PR_PEP_AUTO_CONSUME_NAME, StringComparison.OrdinalIgnoreCase)))
+                                            {
+                                                outValue = header.Value.Trim();
+                                            }
+                                        }
                                     }
                                 }
 
@@ -1016,19 +1071,24 @@
                                 {
                                     outValue = true;
                                 }
-                                // Fallback solution for when the property doesn't get set correctly as MAPI property in an Exchange
-                                // server environment and therefore has to be retrieved directly from the message's internet headers.
-                                // This is not ideal, as the fallback will only be needed for some edge cases, but the logic is run 
-                                // several times for each mail item.
                                 else
                                 {
-                                    messageHeaders = MapiHelper.GetProperty(omi, MapiProperty.PidTagTransportMessageHeaders) as string;
-
-                                    if ((string.IsNullOrEmpty(messageHeaders) == false) &&
-                                        (messageHeaders.ToUpperInvariant().Contains(PEPMessage.PR_PEP_NEVER_UNSECURE_NAME.ToUpperInvariant())))
+                                    // Fallback solution for when the property doesn't get set correctly as MAPI property in an Exchange
+                                    // server environment and therefore has to be retrieved directly from the message's internet headers.
+                                    // This is not ideal, as the fallback will only be needed for some edge cases, but the logic is run 
+                                    // several times for each mail item.
+                                    messageHeaders = omi.GetParsedTransportMessageHeaders();
+                                    if (messageHeaders != null)
                                     {
-                                        Log.Info("MailItemExtensions.GetPEPProperty: NeverUnsecure property retrieved using fallback solution.");
-                                        outValue = true;
+                                        foreach (Header header in messageHeaders)
+                                        {
+                                            if ((header.Field != null) &&
+                                                (string.Equals(header.Field.Trim(), PEPMessage.PR_PEP_NEVER_UNSECURE_NAME, StringComparison.OrdinalIgnoreCase)))
+                                            {
+                                                Log.Verbose("MailItemExtensions.GetPEPProperty: NeverUnsecure property retrieved using fallback solution.");
+                                                outValue = true;
+                                            }
+                                        }
                                     }
                                 }
 
Binary file Resources/Credits.rtf has changed
--- a/pEpForOutlook.csproj	Mon Oct 31 14:32:21 2016 +0100
+++ b/pEpForOutlook.csproj	Mon Oct 31 16:19:52 2016 +0100
@@ -218,6 +218,10 @@
       <EmbedInteropTypes>False</EmbedInteropTypes>
     </Reference>
     <Reference Include="Microsoft.VisualStudio.Tools.Applications.Runtime, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="MimeKitLite, Version=1.10.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814, processorArchitecture=MSIL">
+      <HintPath>..\packages\MimeKitLite.1.10.0\lib\net40\MimeKitLite.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="Office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
       <EmbedInteropTypes>True</EmbedInteropTypes>
     </Reference>
@@ -238,6 +242,7 @@
     <Reference Include="System" />
     <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Security" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Windows.Presentation" />
     <Reference Include="System.Xaml" />
@@ -448,6 +453,7 @@
       <SubType>Designer</SubType>
     </EmbeddedResource>
     <None Include="app.config" />
+    <None Include="packages.config" />
     <None Include="pep_test.snk" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packages.config	Mon Oct 31 16:19:52 2016 +0100
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MimeKitLite" version="1.10.0" targetFramework="net40-client" />
+</packages>
\ No newline at end of file