Beispiel #1
0
    internal override async Task DeserializeOverrideAsync(BoundedStream stream, EventShuttle eventShuttle,
                                                          CancellationToken cancellationToken)
    {
        var rootStream = GetRootStream(stream);

        var length = GetFieldLength();

        Value = length != null
            ? new Streamlet(rootStream, rootStream.Position, length.ByteCount)
            : new Streamlet(rootStream, rootStream.Position);

        if (length != null)
        {
            var nullStream = new NullStream();
            await stream.CopyToAsync(nullStream, (int)length.ByteCount, CopyToBufferSize, cancellationToken)
            .ConfigureAwait(false);
        }
        else
        {
            stream.Seek(0, SeekOrigin.End);
        }
    }
Beispiel #2
0
        /// <summary>
        /// If "*****@*****.**" is replying to something sent to "*****@*****.**",
        /// replace the "me@example" in the mail
        /// </summary>
        public static async Task <(Stream, string)> ReplaceSenderAsync(
            IDictionary <string, IEnumerable <string> > headers,
            Stream bodyStream,
            string sender,
            CancellationToken token)
        {
            bodyStream.Seek(0, SeekOrigin.Begin);

            if (!headers.TryGetValue("References", out IEnumerable <string> referenes))
            {
                return(bodyStream, sender);
            }

            foreach (var r in referenes)
            {
                Match match = ReferenceOriginalSender.Match(r);
                if (match.Success)
                {
                    var senderParts = sender.Split('@', 2);
                    if (senderParts.Length != 2)
                    {
                        // Not a useful email address...
                        continue;
                    }

                    var headerSender = match.Groups[1].Value;
                    var headerParts  = headerSender.Split('@', 2);
                    if (headerParts.Length != 2)
                    {
                        // Not a useful email address...
                        continue;
                    }

                    if (senderParts[1] != headerParts[1])
                    {
                        // Wrong domain...
                        continue;
                    }

                    if (!headerParts[0].StartsWith(senderParts[0] + "-"))
                    {
                        // Doesn't start with correct extension root
                        continue;
                    }

                    MemoryStream replacedStream = null;
                    try
                    {
                        replacedStream = new MemoryStream();

                        MimeReader reader    = new MimeReader();
                        var        structure = await reader.ReadStructureAsync(bodyStream, token);

                        // Copy the preamble
                        bodyStream.Seek(0, SeekOrigin.Begin);
                        BoundedStream pre = new BoundedStream(bodyStream, structure.HeaderSpan.Start);
                        await pre.CopyToAsync(replacedStream, token);

                        // Replace stuff in headers
                        bodyStream.Seek(structure.HeaderSpan.Start, SeekOrigin.Begin);
                        var headerBytes = await bodyStream.ReadExactlyAsync((int)structure.HeaderSpan.Length, token);

                        string header = Encoding.ASCII.GetString(headerBytes);
                        header = ReplaceFrom.Replace(header, $"$1<{headerSender}>");
                        header = ReplaceReferences.Replace(header,
                                                           m =>
                        {
                            if (String.IsNullOrWhiteSpace(m.Groups["pre"].Value) &&
                                String.IsNullOrWhiteSpace(m.Groups["post"].Value))
                            {
                                // We were the ONLY references header, just remove the whole thing
                                return("");
                            }

                            string space = "";
                            if (!String.IsNullOrEmpty(m.Groups["preSpace"].Value) &&
                                !String.IsNullOrEmpty(m.Groups["postSpace"].Value))
                            {
                                space = m.Groups["preSpace"].Value;
                            }

                            return($"References:{m.Groups["pre"].Value}{space}{m.Groups["post"].Value}");
                        });

                        using (StreamWriter writer = new StreamWriter(replacedStream, Encoding.ASCII, 1024, true))
                        {
                            writer.Write(header);
                        }

                        // Copy message content
                        bodyStream.Seek(structure.HeaderSpan.End, SeekOrigin.Begin);
                        await bodyStream.CopyToAsync(replacedStream, token);

                        bodyStream.Dispose();
                        replacedStream.Seek(0, SeekOrigin.Begin);

                        return(replacedStream, headerSender);
                    }
                    catch
                    {
                        replacedStream?.Dispose();
                        throw;
                    }
                }
            }

            return(bodyStream, sender);
        }