public object Parse(string value, object argument)
        {
            var index = value.IndexOf(Characters.Colon);

            value = value.Substring(index + 1).Trim();
            return(TransferEncoder.DecodeHeaderIfNecessary(value));
        }
Beispiel #2
0
        public string Serialize()
        {
            using (var writer = new StringWriter()) {
                foreach (var literals in Headers.Select(headerField => headerField.Serialize()))
                {
                    writer.WriteLine(literals);
                }

                var isSingleView = CheckSingleView();
                if (isSingleView)
                {
                    var child = Children.First();
                    writer.WriteLine(string.Empty);
                    writer.WriteLine(child.Text);
                    return(writer.ToString());
                }

                var isMultipart = CheckMultipart();
                if (isMultipart)
                {
                    writer.WriteLine(string.Empty);
                    writer.WriteLine("This is a multi-part message in MIME format.");

                    foreach (var child in Children)
                    {
                        writer.WriteLine(string.Empty);
                        writer.WriteLine("--" + ContentTypeHeaderField.BoundaryName);
                        var part = child.Serialize();
                        writer.WriteLine(part);
                    }

                    writer.WriteLine("--" + ContentTypeHeaderField.BoundaryName + "--");
                }
                else
                {
                    var encoding    = DetermineEncoding();
                    var contentType = DetermineContentType();
                    switch (contentType)
                    {
                    case ContentTypes.MessageRfc822:
                        encoding = ContentTransferEncodings.None;
                        break;
                    }
                    var charset = DetermineCharset();

                    var encodedBody = !string.IsNullOrEmpty(Text)
                                          ? TransferEncoder.Encode(Text, encoding, charset)                             // is text, needs encoding
                                          : Bytes != null?Convert.ToBase64String(Bytes).ToBlockText(76) : string.Empty; // is binary stream, needs no encoding

                    writer.Write(Environment.NewLine);
                    writer.Write(encodedBody);
                }

                return(writer.ToString());
            }
        }
Beispiel #3
0
        public virtual void Deserialize(string literals)
        {
            var index = literals.IndexOf(":");

            Name = literals.Substring(0, index);

            var tail = literals.Substring(index + 1).Trim();

            var decodedText = TransferEncoder.DecodeHeaderIfNecessary(tail);


            ParseRemainder(decodedText);
        }
Beispiel #4
0
        public virtual string Serialize()
        {
            if (Parameters.Count > 0)
            {
                var parameters = Parameters.Serialize();
                return(string.Format("{0}: {1};{2} {3}", Name, Value, Environment.NewLine, parameters));
            }

            // encode if necessary
            var value = TransferEncoder.EncodeHeaderIfNecessary(Value, HeaderEncoding);


            return(string.Format("{0}: {1}", Name, value));
        }
Beispiel #5
0
        /// <summary>
        /// Fetches a single view from the requested message.
        /// </summary>
        /// <param name="info">The associated info object, this token can be obtained from the messages body structure.</param>
        /// <returns>The requested view.</returns>
        public View FetchView2(ViewInfo info)
        {
            var text = FetchEntityBody(info);

            if (string.IsNullOrEmpty(text))
            {
                return(null);
            }
            var paramDictionary = ((IDictionary <string, string>)info.Parameters);
            var hasValidCharset = paramDictionary.ContainsKey("charset");
            var charset         = hasValidCharset ? paramDictionary["charset"] : Charsets.Utf8;
            var decoded         = TransferEncoder.Decode(text, info.ContentTransferEncoding, charset);

            return(new View {
                MediaType = info.MediaType, Text = decoded
            });
        }
Beispiel #6
0
        public BoundaryTy readBody(TextReader rr, EML_Media parent)
        {
            mlBody   = null;
            mlBinary = null;

            string major = mlContentType.major;

            string boundary = parent.mlContentType.boundary;

            bool binaryMedia = !major.Equals("text");

            string         charSet     = mlContentType.charSet;
            CharsetEncoder charSet_enc = charSetEnc.getEncoding(charSet);

            if (charSet_enc == null)
            {
                throw new ArgumentException("不明な文字コード", charSet);
            }

            string          transferEncoding = parent.mlContentTransferEncoding.major;
            TransferEncoder transfer_enc     = transferEnc.getEncoding(transferEncoding);

            if (transfer_enc == null)
            {
                throw new ArgumentException("不明な変換コード", transferEncoding);
            }

            mlBody   = new StringBuilder();
            mlBinary = new MemoryStream();

            String boundaryPass = (boundary != null)
                ? "--" + boundary
                : null
            ;
            String boundaryTerm = (boundary != null)
                ? "--" + boundary + "--"
                : null
            ;

            MemoryStream tempText = new MemoryStream();

            bool preserveCRLF = transfer_enc.preserveCRLF;

            ArrayList  alDEBUG = new ArrayList();
            BoundaryTy bty     = BoundaryTy.Pass;

            while (true)
            {
                string lin = rr.ReadLine();
                if (lin == null)
                {
                    break;
                }
                alDEBUG.Add(lin);
                if (boundaryTerm != null && lin.Equals(boundaryTerm))
                {
                    bty = BoundaryTy.Term;
                    break;
                }
                if (boundaryPass != null && lin.Equals(boundaryPass))
                {
                    break;
                }
                byte[] bin = transfer_enc.decodeBinary(lin);
                if (binaryMedia)
                {
                    mlBinary.Write(bin, 0, bin.Length);
                    if (preserveCRLF)
                    {
                        mlBinary.WriteByte((byte)'\r');
                        mlBinary.WriteByte((byte)'\n');
                    }
                    continue;
                }
                tempText.Write(bin, 0, bin.Length);
                if (preserveCRLF)
                {
                    tempText.WriteByte((byte)'\r');
                    tempText.WriteByte((byte)'\n');
                }
            }
            if (!binaryMedia)
            {
                string text = charSet_enc.decodeText(tempText.ToArray());
                mlBody.Append(text);
            }
            return(bty);
        }
Beispiel #7
0
        public void writeTo(TextWriter wr)
        {
            if (mlTo != null)
            {
                wr.WriteLine("{0}: {1}", "To", mlTo.ToString());
            }
            if (mlCC != null)
            {
                wr.WriteLine("{0}: {1}", "CC", mlCC.ToString());
            }
            if (mlFrom != null)
            {
                wr.WriteLine("{0}: {1}", "From", mlFrom.ToString());
            }
            if (mlReturnPath != null)
            {
                wr.WriteLine("{0}: {1}", "ReturnPath", mlReturnPath.ToString());
            }
            if (mlReferences != null)
            {
                wr.WriteLine("{0}: {1}", "References", mlReferences.ToString());
            }
            if (mlInReplyTo != null)
            {
                wr.WriteLine("{0}: {1}", "InReplyTo", mlInReplyTo.ToString());
            }
            if (mlMessageID != null)
            {
                wr.WriteLine("{0}: {1}", "MessageID", mlMessageID.ToString());
            }
            if (mlSubject != null)
            {
                wr.WriteLine("{0}: {1}", "Subject", SubjectEncode.current.encode(mlSubject));
            }
            if (mlDate != null)
            {
                wr.WriteLine("{0}: {1}", "Date", mlDate);
            }
            if (mlContentType != null)
            {
                wr.WriteLine("{0}: {1}", "Content-Type", mlContentType);
            }
            if (mlContentTransferEncoding != null)
            {
                wr.WriteLine("{0}: {1}", "Content-Transfer-Encoding", mlContentTransferEncoding);
            }
            if (mlContentDisposition != null)
            {
                wr.WriteLine("{0}: {1}", "Content-Disposition", mlContentDisposition);
            }
            wr.WriteLine("{0}: {1}", "MIME-Version", "1.0");
            wr.WriteLine("{0}: {1}", "X-Mailer", "HDD LibEML 1.0");

            string          transferEncoding = mlContentTransferEncoding.major;
            TransferEncoder transfer_enc     = transferEnc.getEncoding(transferEncoding);

            string         charSet     = mlContentType.charSet;
            CharsetEncoder charSet_enc = charSetEnc.getEncoding(charSet);

            wr.WriteLine();

            if (mlBody != null)
            {
                byte[] bin = charSet_enc.encodeText(mlBody.ToString());

                if (transfer_enc == null)
                {
                    throw new ArgumentException("不明な変換コード", transferEncoding);
                }

                wr.Write(transfer_enc.encodeBinary(bin));
            }
            else
            {
                if (transfer_enc == null)
                {
                    throw new ArgumentException("不明な変換コード", transferEncoding);
                }

                mlBinary.Position = 0;

                wr.Write(transfer_enc.encodeBinary(mlBinary.ToArray()));
            }
        }
Beispiel #8
0
        public void Deserialize(string literals)
        {
            var      isBeginning = true;
            LineInfo?last        = null;

            using (var reader = new StringReader(literals)) {
                while (true)
                {
                    var line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    // darn new lines
                    if (line == string.Empty && isBeginning)
                    {
                        continue;
                    }

                    isBeginning = false;
                    var current = new LineInfo(line);
                    if (current.IsField)
                    {
                        if (last.HasValue)
                        {
                            CommitHeaderField(last.Value);
                        }

                        last = current;
                        continue;
                    }

                    if (current.IsContinuation)
                    {
                        if (last.HasValue)
                        {
                            last = last.Value.Merge(current);
                        }
                        continue;
                    }

                    if (!current.IsBoundaryStart && IsBoundaryExpected)
                    {
                        continue;
                    }

                    // process final field
                    if (last.HasValue)
                    {
                        CommitHeaderField(last.Value);
                        last = null;
                    }

                    if (!IsBoundaryExpected)
                    {
                        var charset  = DetermineCharset();
                        var encoding = DetermineEncoding();
                        var content  = reader.ReadToEnd() ?? string.Empty;
                        content.Trim();

                        if (!string.IsNullOrEmpty(content))
                        {
                            if (HasContentType)
                            {
                                var contentType = ContentTypeHeaderField.MediaType;
                                if (encoding == ContentTransferEncodings.Base64 && !contentType.StartsWith("text"))
                                {
                                    Bytes = string.IsNullOrEmpty(content) ? new byte[0] : Convert.FromBase64String(content);
                                }
                                else
                                {
                                    Text = TransferEncoder.Decode(content, encoding, charset);
                                }
                            }
                            else
                            {
                                Text = TransferEncoder.Decode(content, encoding, charset);
                            }
                        }
                        break;
                    }

                    if (current.IsBoundaryStart && IsExpectedBoundary(current))
                    {
                        var parts = ReadBoundaryBlocks(current.BoundaryName, reader);
                        foreach (var part in parts)
                        {
                            var entity = new Entity();
                            entity.Deserialize(part);
                            Children.Add(entity);
                        }
                    }
                }
            }
        }
Beispiel #9
0
        public object Parse(string text, object argument)
        {
            var envelope = new Envelope();

            // quotes inside the subject can trash the regex results, therefor we will tempararily replace them
            text = text.Replace("\\\"", "&,,4+");

            var matches = Regex.Matches(text, RegexPatterns.EnvelopeResponsePattern);

            if (matches.Count != 10)
            {
                Debug.WriteLine(FailureMessages.UnexpectedItemCountInEnvelopeMessage);
                Debug.WriteLine("Response: " + text);
                return(envelope);
            }

            DateTime date;
            var      normalized = TransferEncoder.DecodeHeaderIfNecessary(matches[0].Value).TrimQuotes().RemoveComments();
            var      success    = DateTime.TryParse(normalized, out date);

            if (success)
            {
                envelope.Date = date;
            }
            else
            {
                Debug.WriteLine(FailureMessages.UnexpectedDateFormatMessage);
                Debug.WriteLine("Date: " + normalized);
            }

            envelope.Subject = matches[1].Value.TrimQuotes();

            // need to insert the previously replaced quotes
            envelope.Subject = envelope.Subject.Replace("&,,4+", "\"");
            envelope.Subject = TransferEncoder.DecodeHeaderIfNecessary(envelope.Subject);

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[2].Value);
                var from  = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.From).AddRange(from);
            }

            {
                var value  = TransferEncoder.DecodeHeaderIfNecessary(matches[3].Value);
                var sender = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.Sender).AddRange(sender);
            }

            {
                var value   = TransferEncoder.DecodeHeaderIfNecessary(matches[4].Value);
                var replyTo = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.ReplyTo).AddRange(replyTo);
            }

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[5].Value);
                var to    = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.To).AddRange(to);
            }

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[6].Value);
                var cc    = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.Cc).AddRange(cc);
            }

            {
                var value = TransferEncoder.DecodeHeaderIfNecessary(matches[7].Value);
                var bcc   = ParseContacts(value.TrimQuotes());
                ((List <EmailContact>)envelope.Bcc).AddRange(bcc);
            }

            var inReplyTo = TransferEncoder.DecodeHeaderIfNecessary(matches[8].Value).TrimQuotes();

            envelope.InReplyTo = inReplyTo.IsNilOrEmpty() ? string.Empty : inReplyTo;

            var messageId = TransferEncoder.DecodeHeaderIfNecessary(matches[9].Value).TrimQuotes();

            envelope.MessageId = messageId.IsNilOrEmpty() ? string.Empty : messageId;

            return(envelope);
        }
Beispiel #10
0
        public string ReadSection(ImapResponseReader reader)
        {
            var text = reader.CurrentLine;
            var sn   = Regex.Match(text, @"\d+").Value;


            using (var sw = new StringWriter()) {
                using (var sr = new StringReader(text)) {
                    var stack = new Stack <char>();

                    var isStarted = false;
                    var index     = text.IndexOf("BODYSTRUCTURE");
                    var buffer    = new char[index + 1];
                    sr.Read(buffer, 0, index);

                    while (true)
                    {
                        if (isStarted)
                        {
                            sw.Write(buffer[0]);
                        }

                        var count = sr.Read(buffer, 0, 1);

                        // end of string
                        if (count == 0)
                        {
                            break;
                        }

                        // matching brace found
                        if (isStarted && stack.Count == 0)
                        {
                            break;
                        }

                        if (buffer[0] == Characters.RoundOpenBracket)
                        {
                            stack.Push(buffer[0]);
                            isStarted = true;
                            continue;
                        }

                        if (buffer[0] == Characters.RoundClosedBracket)
                        {
                            stack.Pop();
                            continue;
                        }
                    }

                    // is a size appended to indicate multilined data? {####}
                    var sizeMatch = Regex.Match(reader.CurrentLine, @"\{\d+\}$");
                    if (sizeMatch.Success)
                    {
                        // need to remove {####} from end of string
                        sw.RemoveLast(sizeMatch.Value.Length);

                        // Usually we could determine the amount of data to read from the size parameter at the end of the line
                        // unfortunately here the number contained seems to be completely arbitrary since it never fits, coming from 1und1 its always 107, no matter what follows.
                        // The 'only' thing I can be sure of when determining the amount of data to append is that it has to end with a closing bracket, no matter what.
                        while (true)
                        {
                            reader.ReadNextLine();
                            var line = reader.CurrentLine;
                            sizeMatch = Regex.Match(reader.CurrentLine, @"\{\d+\}$");

                            // cut trailing {###} expression if necessary
                            var normalizedLine = sizeMatch.Success ? line.Substring(0, line.Length - sizeMatch.Value.Length) : line;

                            // decode line since its usually encoded using QP or Base64
                            normalizedLine = TransferEncoder.DecodeHeaderIfNecessary(normalizedLine);

                            // append line to regular body struct
                            sw.Write(normalizedLine);
                            if (reader.CurrentLine.EndsWith(")"))
                            {
                                break;
                            }
                        }
                    }

                    // we silently append the sequence number to the end of the body structure,
                    // the parser will ignore it, but we can read it later without having to split or change this string
                    sw.Write(Characters.Space);
                    sw.Write(sn);
                    return(sw.ToString());
                }
            }
        }