Skip to content

Commit

Permalink
Added new MimeMessage .ctor that takes IEnumerable<Header>
Browse files Browse the repository at this point in the history
  • Loading branch information
jstedfast committed Dec 20, 2024
1 parent affbcd7 commit b83c82a
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 3 deletions.
47 changes: 47 additions & 0 deletions MimeKit/MimeMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,46 @@ public MimeMessage (params object[] args) : this (ParserOptions.Default.Clone ()
MessageId = MimeUtils.GenerateMessageId ();
}

/// <summary>
/// Initialize a new instance of the <see cref="MimeMessage"/> class.
/// </summary>
/// <remarks>
/// Creates a new <see cref="MimeMessage"/>.
/// </remarks>
/// <param name="headers">A list of initial message headers.</param>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="headers"/> is <see langword="null"/>.
/// </exception>
public MimeMessage (IEnumerable<Header> headers)
{
if (headers is null)
throw new ArgumentNullException (nameof (headers));

addresses = new Dictionary<HeaderId, InternetAddressList> ();
compliance = RfcComplianceMode.Strict;

// initialize our address lists
foreach (var id in StandardAddressHeaders) {
var list = new InternetAddressList ();
list.Changed += InternetAddressListChanged;
addresses.Add (id, list);
}

references = new MessageIdList ();
references.Changed += ReferencesChanged;

if (headers is HeaderList headerList) {
Headers = headerList;
} else {
Headers = new HeaderList (ParserOptions.Default);

foreach (var header in headers)
Headers.Add (header);
}

Headers.Changed += HeadersChanged;
}

/// <summary>
/// Initialize a new instance of the <see cref="MimeMessage"/> class.
/// </summary>
Expand All @@ -231,6 +271,13 @@ public MimeMessage (params object[] args) : this (ParserOptions.Default.Clone ()
/// <param name="to">The list of addresses in the To header.</param>
/// <param name="subject">The subject of the message.</param>
/// <param name="body">The body of the message.</param>
/// <exception cref="System.ArgumentNullException">
/// <para><paramref name="from"/> is <see langword="null"/>.</para>
/// <para>-or-</para>
/// <para><paramref name="to"/> is <see langword="null"/>.</para>
/// <para>-or-</para>
/// <para><paramref name="subject"/> is <see langword="null"/>.</para>
/// </exception>
public MimeMessage (IEnumerable<InternetAddress> from, IEnumerable<InternetAddress> to, string subject, MimeEntity body) : this ()
{
From.AddRange (from);
Expand Down
131 changes: 128 additions & 3 deletions UnitTests/MimeMessageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ public void TestArgumentExceptions ()
{
var unknown = new Cryptography.UnknownCryptographyContext ();
var message = new MimeMessage ();
var body = new TextPart ("plain") {
Text = "This is the message body."
};

Assert.Throws<ArgumentNullException> (() => new MimeMessage ((IEnumerable<Header>) null));
Assert.Throws<ArgumentNullException> (() => new MimeMessage (null, Array.Empty<InternetAddress> (), string.Empty, body));
Assert.Throws<ArgumentNullException> (() => new MimeMessage (Array.Empty<InternetAddress> (), null, string.Empty, body));
Assert.Throws<ArgumentNullException> (() => new MimeMessage (Array.Empty<InternetAddress> (), Array.Empty<InternetAddress> (), null, body));

Assert.Throws<ArgumentOutOfRangeException> (() => message.Importance = (MessageImportance) 500);
Assert.Throws<ArgumentOutOfRangeException> (() => message.Priority = (MessagePriority) 500);
Expand Down Expand Up @@ -95,9 +103,6 @@ public void TestArgumentExceptions ()
var sender = new MailboxAddress ("MimeKit UnitTests", "[email protected]");
message.From.Add (sender);
message.To.Add (new MailboxAddress ("MimeKit UnitTests", "[email protected]"));
var body = new TextPart ("plain") {
Text = "This is the message body."
};

Assert.Throws<ArgumentNullException> (() => message.Sign (null));
Assert.Throws<ArgumentNullException> (() => message.Sign (null, DigestAlgorithm.Sha1));
Expand Down Expand Up @@ -835,6 +840,126 @@ public async Task TestReserializationDeliveryStatusReportWithEnsureNewLine ()
}
}

[Test]
public async Task TestReserializationNewFromHeaderList ()
{
string rawRfc822Headers = @"X-Andrew-Authenticated-As: 4099;greenbush.galaxy;Nathaniel Borenstein
Received: from Messages.8.5.N.CUILIB.3.45.SNAP.NOT.LINKED.greenbush.galaxy.sun4.41
via MS.5.6.greenbush.galaxy.sun4_41;
Fri, 12 Jun 1992 13:29:05 -0400 (EDT)
Message-ID : <[email protected]>
Date: Fri, 12 Jun 1992 13:29:05 -0400 (EDT)
From: Nathaniel Borenstein <nsb>
X-Andrew-Message-Size: 152+1
MIME-Version: 1.0
To: Ned Freed <[email protected]>,
[email protected] (Yutaka Sato =?ISO-2022-JP?B?GyRAOjRGI0stGyhK?= )
Subject: MIME & int'l mail
".Replace ("\r\n", "\n");

using (var source = new MemoryStream (Encoding.UTF8.GetBytes (rawRfc822Headers))) {
var headers = HeaderList.Load (source);
var message = new MimeMessage (headers);

Assert.That (message.Date, Is.EqualTo (new DateTimeOffset (1992, 6, 12, 13, 29, 05, TimeSpan.FromHours (-4))), "Date");
Assert.That (message.From.Count, Is.EqualTo (1), "From.Count");
var from = message.From.Mailboxes.First ();
Assert.That (from.Name, Is.EqualTo ("Nathaniel Borenstein"), "From.Name");
Assert.That (from.Address, Is.EqualTo ("nsb"), "From.Address");
Assert.That (message.To.Count, Is.EqualTo (2), "To.Count");
var to = message.To.Mailboxes.ToList ();
Assert.That (to[0].Name, Is.EqualTo ("Ned Freed"), "To[0].Name");
Assert.That (to[0].Address, Is.EqualTo ("[email protected]"), "To[0].Address");
Assert.That (to[1].Name, Is.EqualTo ("Yutaka Sato 佐藤豊"), "To[1].Name");
Assert.That (to[1].Address, Is.EqualTo ("[email protected]"), "To[1].Address");
Assert.That (message.Subject, Is.EqualTo ("MIME & int'l mail"), "Subject");

// Test reserialization of the rfc822 headers
using (var serialized = new MemoryStream ()) {
var options = FormatOptions.Default.Clone ();
options.NewLineFormat = NewLineFormat.Unix;

message.WriteTo (options, serialized);

var result = Encoding.UTF8.GetString (serialized.ToArray ());

Assert.That (result, Is.EqualTo (rawRfc822Headers), "Reserialized message is not identical to the original.");
}

using (var serialized = new MemoryStream ()) {
var options = FormatOptions.Default.Clone ();
options.NewLineFormat = NewLineFormat.Unix;

await message.WriteToAsync (options, serialized);

var result = Encoding.UTF8.GetString (serialized.ToArray ());

Assert.That (result, Is.EqualTo (rawRfc822Headers), "Reserialized message is not identical to the original.");
}
}
}

[Test]
public async Task TestReserializationNewFromIEnumerableHeader ()
{
string rawRfc822Headers = @"X-Andrew-Authenticated-As: 4099;greenbush.galaxy;Nathaniel Borenstein
Received: from Messages.8.5.N.CUILIB.3.45.SNAP.NOT.LINKED.greenbush.galaxy.sun4.41
via MS.5.6.greenbush.galaxy.sun4_41;
Fri, 12 Jun 1992 13:29:05 -0400 (EDT)
Message-ID : <[email protected]>
Date: Fri, 12 Jun 1992 13:29:05 -0400 (EDT)
From: Nathaniel Borenstein <nsb>
X-Andrew-Message-Size: 152+1
MIME-Version: 1.0
To: Ned Freed <[email protected]>,
[email protected] (Yutaka Sato =?ISO-2022-JP?B?GyRAOjRGI0stGyhK?= )
Subject: MIME & int'l mail
".Replace ("\r\n", "\n");

using (var source = new MemoryStream (Encoding.UTF8.GetBytes (rawRfc822Headers))) {
var headers = HeaderList.Load (source).ToList ();
var message = new MimeMessage (headers);

Assert.That (message.Date, Is.EqualTo (new DateTimeOffset (1992, 6, 12, 13, 29, 05, TimeSpan.FromHours (-4))), "Date");
Assert.That (message.From.Count, Is.EqualTo (1), "From.Count");
var from = message.From.Mailboxes.First ();
Assert.That (from.Name, Is.EqualTo ("Nathaniel Borenstein"), "From.Name");
Assert.That (from.Address, Is.EqualTo ("nsb"), "From.Address");
Assert.That (message.To.Count, Is.EqualTo (2), "To.Count");
var to = message.To.Mailboxes.ToList ();
Assert.That (to[0].Name, Is.EqualTo ("Ned Freed"), "To[0].Name");
Assert.That (to[0].Address, Is.EqualTo ("[email protected]"), "To[0].Address");
Assert.That (to[1].Name, Is.EqualTo ("Yutaka Sato 佐藤豊"), "To[1].Name");
Assert.That (to[1].Address, Is.EqualTo ("[email protected]"), "To[1].Address");
Assert.That (message.Subject, Is.EqualTo ("MIME & int'l mail"), "Subject");

// Test reserialization of the rfc822 headers
using (var serialized = new MemoryStream ()) {
var options = FormatOptions.Default.Clone ();
options.NewLineFormat = NewLineFormat.Unix;

message.WriteTo (options, serialized);

var result = Encoding.UTF8.GetString (serialized.ToArray ());

Assert.That (result, Is.EqualTo (rawRfc822Headers), "Reserialized message is not identical to the original.");
}

using (var serialized = new MemoryStream ()) {
var options = FormatOptions.Default.Clone ();
options.NewLineFormat = NewLineFormat.Unix;

await message.WriteToAsync (options, serialized);

var result = Encoding.UTF8.GetString (serialized.ToArray ());

Assert.That (result, Is.EqualTo (rawRfc822Headers), "Reserialized message is not identical to the original.");
}
}
}

[Test]
public void TestMailMessageToMimeMessage ()
{
Expand Down

0 comments on commit b83c82a

Please sign in to comment.