Fixing issues with replies.

This commit is contained in:
Burak Kaan Köse
2026-04-07 01:17:52 +02:00
parent 12acff3bf8
commit 9855170b2e
8 changed files with 408 additions and 105 deletions
@@ -1,10 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Wino.Core.Domain.Extensions;
public static class MailHeaderExtensions
{
public static string NormalizeMessageId(string value)
{
if (value == null)
return null;
var normalized = StripAngleBrackets(value)?.Trim();
return string.IsNullOrWhiteSpace(normalized) ? string.Empty : normalized;
}
public static string ToHeaderMessageId(string value)
{
var normalized = NormalizeMessageId(value);
return string.IsNullOrEmpty(normalized) ? string.Empty : $"<{normalized}>";
}
/// <summary>
/// Strips angle brackets from a Message-ID or In-Reply-To value.
/// RFC 5322 Message-IDs are formatted as &lt;id@domain&gt;, but MimeKit
@@ -29,14 +45,53 @@ public static class MailHeaderExtensions
/// like "&lt;id1@domain&gt; &lt;id2@domain&gt;". This converts them to "id1@domain;id2@domain".
/// </summary>
public static string NormalizeReferences(string rawReferences)
=> JoinStoredReferences(SplitMessageIds(rawReferences));
public static IEnumerable<string> SplitMessageIds(string values)
{
if (string.IsNullOrEmpty(rawReferences)) return rawReferences;
if (string.IsNullOrWhiteSpace(values))
return [];
var ids = rawReferences
return values
.Split(new[] { ' ', '\t', '\r', '\n', ';', ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(StripAngleBrackets)
.Select(NormalizeMessageId)
.Where(id => !string.IsNullOrEmpty(id));
}
return string.Join(";", ids);
public static string JoinStoredReferences(IEnumerable<string> values)
=> string.Join(";", NormalizeDistinctMessageIds(values));
public static string BuildReferencesHeaderValue(IEnumerable<string> values)
=> string.Join(" ", NormalizeDistinctMessageIds(values).Select(ToHeaderMessageId));
public static List<string> BuildReferencesChain(IEnumerable<string> existingReferences, string parentMessageId)
{
var results = NormalizeDistinctMessageIds(existingReferences).ToList();
var normalizedParentMessageId = NormalizeMessageId(parentMessageId);
if (!string.IsNullOrEmpty(normalizedParentMessageId) &&
!results.Contains(normalizedParentMessageId, StringComparer.OrdinalIgnoreCase))
{
results.Add(normalizedParentMessageId);
}
return results;
}
private static IEnumerable<string> NormalizeDistinctMessageIds(IEnumerable<string> values)
{
if (values == null)
yield break;
var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var value in values)
{
var normalized = NormalizeMessageId(value);
if (string.IsNullOrEmpty(normalized) || !seen.Add(normalized))
continue;
yield return normalized;
}
}
}