/// <summary> /// Reads SMTP "Mailbox" from the specified MIME reader. /// </summary> /// <param name="reader">MIME reader.</param> /// <returns>Returns SMTP "Mailbox" or null if no SMTP mailbox available.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>reader</b> is null reference.</exception> internal static string SMTP_Mailbox(MIME_Reader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } // TODO: /* RFC 5321. Mailbox = Local-part "@" ( Domain / address-literal ) Local-part = Dot-string / Quoted-string ; MAY be case-sensitive Dot-string = Atom *("." Atom) */ StringBuilder retVal = new StringBuilder(); if (reader.Peek(true) == '\"') { retVal.Append("\"" + reader.QuotedString() + "\""); } else { retVal.Append(reader.DotAtom()); } if (reader.Peek(true) != '@') { return null; ; } else { // Eat "@". reader.Char(true); retVal.Append('@'); retVal.Append(reader.DotAtom()); } return retVal.ToString(); }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Sender: [email protected]'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_Mailbox Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new char[] { ':' }, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } MIME_Reader r = new MIME_Reader(name_value[1].Trim()); string word = r.QuotedReadToDelimiter(new char[] { ',', '<', ':' }); // Invalid value. if (word == null) { throw new ParseException("Invalid header field value '" + value + "'."); } // name-addr else if (r.Peek(true) == '<') { Mail_h_Mailbox h = new Mail_h_Mailbox(name_value[0], new Mail_t_Mailbox(word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word)) : null, r.ReadParenthesized())); h.m_ParseValue = value; return(h); } // addr-spec else { Mail_h_Mailbox h = new Mail_h_Mailbox(name_value[0], new Mail_t_Mailbox(null, word)); h.m_ParseValue = value; return(h); } }
/// <summary> /// Parses <b>mailbox-list</b> from specified string value. /// </summary> /// <param name="value">The <b>mailbox-list</b> string value.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when <b>value</b> is not valid <b>mailbox-list</b> value.</exception> public static Mail_t_MailboxList Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } MIME_Reader r = new MIME_Reader(value); Mail_t_MailboxList retVal = new Mail_t_MailboxList(); while (true) { string word = r.QuotedReadToDelimiter(new char[] { ',', '<' }); // We processed all data. if (string.IsNullOrEmpty(word) && r.Available == 0) { break; } // name-addr else if (r.Peek(true) == '<') { retVal.Add(new Mail_t_Mailbox(word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word.Trim())) : null, r.ReadParenthesized())); } // addr-spec else { retVal.Add(new Mail_t_Mailbox(null, word)); } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } return(retVal); }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Content-Type: text/plain'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_MailboxList Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new[] { ':' }, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } /* RFC 5322 3.4. * mailbox = name-addr / addr-spec * * name-addr = [display-name] angle-addr * * angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr * * display-name = phrase * * mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list */ MIME_Reader r = new MIME_Reader(MIME_Utils.UnfoldHeader(name_value.Length == 2 ? name_value[1].TrimStart() : "")); Mail_h_MailboxList retVal = new Mail_h_MailboxList(name_value[0], new Mail_t_MailboxList()); while (true) { string word = r.QuotedReadToDelimiter(new[] { ',', '<', ':' }); // We processed all data. if (word == null && r.Available == 0) { break; } // name-addr else if (r.Peek(true) == '<') { retVal.m_pAddresses.Add( new Mail_t_Mailbox( word != null ? MIME_Encoding_EncodedWord.DecodeAll(word) : null, r.ReadParenthesized())); } // addr-spec else { retVal.m_pAddresses.Add(new Mail_t_Mailbox(null, word)); } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } retVal.m_ParseValue = value; retVal.m_pAddresses.AcceptChanges(); return(retVal); }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Content-Type: text/plain'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_MailboxList Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new[] {':'}, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } /* RFC 5322 3.4. mailbox = name-addr / addr-spec name-addr = [display-name] angle-addr angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr display-name = phrase mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list */ MIME_Reader r = new MIME_Reader(MIME_Utils.UnfoldHeader(name_value.Length == 2 ? name_value[1].TrimStart() : "")); Mail_h_MailboxList retVal = new Mail_h_MailboxList(name_value[0], new Mail_t_MailboxList()); while (true) { string word = r.QuotedReadToDelimiter(new[] {',', '<', ':'}); // We processed all data. if (word == null && r.Available == 0) { break; } // name-addr else if (r.Peek(true) == '<') { retVal.m_pAddresses.Add( new Mail_t_Mailbox( word != null ? MIME_Encoding_EncodedWord.DecodeAll(word) : null, r.ReadParenthesized())); } // addr-spec else { retVal.m_pAddresses.Add(new Mail_t_Mailbox(null, word)); } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } retVal.m_ParseValue = value; retVal.m_pAddresses.AcceptChanges(); return retVal; }
/// <summary> /// Parses <b>address-list</b> from specified string value. /// </summary> /// <param name="value">The <b>address-list</b> string value.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when <b>value</b> is not valid <b>address-list</b> value.</exception> public static Mail_t_AddressList Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } /* RFC 5322 3.4. * address = mailbox / group * mailbox = name-addr / addr-spec * name-addr = [display-name] angle-addr * angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr * group = display-name ":" [group-list] ";" [CFWS] * display-name = phrase * mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list * address-list = (address *("," address)) / obs-addr-list * group-list = mailbox-list / CFWS / obs-group-list */ MIME_Reader r = new MIME_Reader(value); Mail_t_AddressList retVal = new Mail_t_AddressList(); while (true) { string word = r.QuotedReadToDelimiter(new char[] { ',', '<', ':' }); // We processed all data. if (word == null && r.Available == 0) { break; } // group else if (r.Peek(true) == ':') { Mail_t_Group group = new Mail_t_Group(word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word)) : null); // Consume ':' r.Char(true); while (true) { word = r.QuotedReadToDelimiter(new char[] { ',', '<', ':', ';' }); // We processed all data. if ((word == null && r.Available == 0) || r.Peek(false) == ';') { break; } // In valid address list value. else if (word == string.Empty) { throw new ParseException("Invalid address-list value '" + value + "'."); } // name-addr else if (r.Peek(true) == '<') { group.Members.Add(new Mail_t_Mailbox(word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word)) : null, r.ReadParenthesized())); } // addr-spec else { group.Members.Add(new Mail_t_Mailbox(null, word)); } // We reached at the end of group. if (r.Peek(true) == ';') { r.Char(true); break; } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } retVal.Add(group); } // name-addr else if (r.Peek(true) == '<') { retVal.Add(new Mail_t_Mailbox(word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word.Trim())) : null, r.ReadParenthesized())); } // addr-spec else { retVal.Add(new Mail_t_Mailbox(null, word)); } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } return(retVal); }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Sender: [email protected]'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_Received Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new char[] { ':' }, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } Mail_h_Received retVal = new Mail_h_Received("a", "b", DateTime.MinValue); MIME_Reader r = new MIME_Reader(name_value[1]); while (true) { string word = r.Word(); // We processed all data. if (word == null && r.Available == 0) { break; } // We have comment, just eat it. else if (r.StartsWith("(")) { r.ReadParenthesized(); } // We have date-time or unknown-data. else if (r.StartsWith(";")) { // Eat ';' r.Char(false); try{ retVal.m_Time = MIME_Utils.ParseRfc2822DateTime(r.QuotedReadToDelimiter(new char[] { ';' })); } catch { // We hane some unknown data, skip it. } } else { // We have some unexpected char like: .,= ... . Just eat it. if (word == null) { r.Char(true); continue; } word = word.ToUpperInvariant(); if (word == "FROM") { retVal.m_From = r.DotAtom(); r.ToFirstChar(); if (r.StartsWith("(")) { string[] parts = r.ReadParenthesized().Split(' '); if (parts.Length == 1) { if (Net_Utils.IsIPAddress(parts[0])) { retVal.m_pFrom_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[0]), null); } } else if (parts.Length == 2) { if (Net_Utils.IsIPAddress(parts[1])) { retVal.m_pFrom_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[1]), parts[0]); } } } } else if (word == "BY") { retVal.m_By = r.DotAtom(); r.ToFirstChar(); if (r.StartsWith("(")) { string[] parts = r.ReadParenthesized().Split(' '); if (parts.Length == 1) { if (Net_Utils.IsIPAddress(parts[0])) { retVal.m_pBy_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[0]), null); } } else if (parts.Length == 2) { if (Net_Utils.IsIPAddress(parts[1])) { retVal.m_pBy_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[1]), parts[0]); } } } } else if (word == "VIA") { retVal.m_Via = r.Word(); } else if (word == "WITH") { retVal.m_With = r.Word(); } else if (word == "ID") { // msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] if (r.StartsWith("<")) { retVal.m_ID = r.ReadParenthesized(); } else { retVal.m_ID = r.Atom(); } } else if (word == "FOR") { r.ToFirstChar(); // path / angle-address if (r.StartsWith("<")) { retVal.m_For = r.ReadParenthesized(); } else { string mailbox = Mail_Utils.SMTP_Mailbox(r); if (mailbox == null) { throw new ParseException("Invalid Received: For parameter value '" + r.ToEnd() + "'."); } retVal.m_For = mailbox; } } // Unknown, just eat value. else { r.Word(); } } } retVal.m_ParseValue = value; return(retVal); }
public static Mail_t_AddressList ParseAddressList(string value) { MIME_Reader r = new MIME_Reader(value); /* RFC 5322 3.4. address = mailbox / group mailbox = name-addr / addr-spec name-addr = [display-name] angle-addr angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr group = display-name ":" [group-list] ";" [CFWS] display-name = phrase mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list address-list = (address *("," address)) / obs-addr-list group-list = mailbox-list / CFWS / obs-group-list */ Mail_t_AddressList retVal = new Mail_t_AddressList(); while (true) { string word = r.QuotedReadToDelimiter(new[] { ',', '<', ':' }); // We processed all data. if (word == null && r.Available == 0) { if (retVal.Count == 0) { if (CheckEmail(value)) { retVal.Add(new Mail_t_Mailbox(null, value)); } } break; } // skip old group address format else if (r.Peek(true) == ':') { // Consume ':' r.Char(true); } // name-addr else if (r.Peek(true) == '<') { string address = r.ReadParenthesized(); if (CheckEmail(address)) { retVal.Add( new Mail_t_Mailbox( word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word)) : null, address)); } } // addr-spec else { if (CheckEmail(word)) { retVal.Add(new Mail_t_Mailbox(null, word)); } } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } return retVal; }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Sender: [email protected]'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_Mailbox Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new[] {':'}, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } MIME_Reader r = new MIME_Reader(name_value[1]); string word = r.QuotedReadToDelimiter(new[] {',', '<', ':'}); // Invalid value. if (word == null) { throw new ParseException("Invalid header field value '" + value + "'."); } // name-addr else if (r.Peek(true) == '<') { Mail_h_Mailbox h = new Mail_h_Mailbox(name_value[0], new Mail_t_Mailbox( word != null ? MIME_Encoding_EncodedWord.DecodeS( TextUtils.UnQuoteString(word)) : null, r.ReadParenthesized())); h.m_ParseValue = value; return h; } // addr-spec else { Mail_h_Mailbox h = new Mail_h_Mailbox(name_value[0], new Mail_t_Mailbox(null, word)); h.m_ParseValue = value; return h; } }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Sender: [email protected]'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_Received Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new[] {':'}, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } Mail_h_Received retVal = new Mail_h_Received("a", "b", DateTime.MinValue); MIME_Reader r = new MIME_Reader(name_value[1]); while (true) { string word = r.Word(); // We processed all data. if (word == null && r.Available == 0) { break; } // We have comment, just eat it. else if (r.StartsWith("(")) { r.ReadParenthesized(); } // We have date-time. else if (r.StartsWith(";")) { // Eat ';' r.Char(false); retVal.m_Time = MIME_Utils.ParseRfc2822DateTime(r.ToEnd()); } else { // We have some unexpected char like: .,= ... . Just eat it. if (word == null) { r.Char(true); continue; } word = word.ToUpperInvariant(); if (word == "FROM") { retVal.m_From = r.DotAtom(); r.ToFirstChar(); if (r.StartsWith("(")) { string[] parts = r.ReadParenthesized().Split(' '); if (parts.Length == 1) { if (Net_Utils.IsIPAddress(parts[0])) { retVal.m_pFrom_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[0]), null); } } else if (parts.Length == 2) { if (Net_Utils.IsIPAddress(parts[1])) { retVal.m_pFrom_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[1]), parts[0]); } } } } else if (word == "BY") { retVal.m_By = r.DotAtom(); r.ToFirstChar(); if (r.StartsWith("(")) { string[] parts = r.ReadParenthesized().Split(' '); if (parts.Length == 1) { if (Net_Utils.IsIPAddress(parts[0])) { retVal.m_pBy_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[0]), null); } } else if (parts.Length == 2) { if (Net_Utils.IsIPAddress(parts[1])) { retVal.m_pBy_TcpInfo = new Mail_t_TcpInfo(IPAddress.Parse(parts[1]), parts[0]); } } } } else if (word == "VIA") { retVal.m_Via = r.Word(); } else if (word == "WITH") { retVal.m_With = r.Word(); } else if (word == "ID") { // msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] if (r.StartsWith("<")) { retVal.m_ID = r.ReadParenthesized(); } else { retVal.m_ID = r.Atom(); } } else if (word == "FOR") { r.ToFirstChar(); // path / angle-address if (r.StartsWith("<")) { retVal.m_For = r.ReadParenthesized(); } else { string mailbox = Mail_Utils.SMTP_Mailbox(r); if (mailbox == null) { throw new ParseException("Invalid Received: For parameter value '" + r.ToEnd() + "'."); } retVal.m_For = mailbox; } } // Unknown, just eat value. else { r.Word(); } } } retVal.m_ParseValue = value; return retVal; }
public static Mail_t_AddressList ParseAddressList(string value) { MIME_Reader r = new MIME_Reader(value); /* RFC 5322 3.4. * address = mailbox / group * * mailbox = name-addr / addr-spec * * name-addr = [display-name] angle-addr * * angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr * * group = display-name ":" [group-list] ";" [CFWS] * * display-name = phrase * * mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list * * address-list = (address *("," address)) / obs-addr-list * * group-list = mailbox-list / CFWS / obs-group-list */ Mail_t_AddressList retVal = new Mail_t_AddressList(); while (true) { string word = r.QuotedReadToDelimiter(new[] { ',', '<', ':' }); // We processed all data. if (word == null && r.Available == 0) { if (retVal.Count == 0) { if (CheckEmail(value)) { retVal.Add(new Mail_t_Mailbox(null, value)); } } break; } // skip old group address format else if (r.Peek(true) == ':') { // Consume ':' r.Char(true); } // name-addr else if (r.Peek(true) == '<') { string address = r.ReadParenthesized(); if (CheckEmail(address)) { retVal.Add( new Mail_t_Mailbox( word != null ? MIME_Encoding_EncodedWord.DecodeS(TextUtils.UnQuoteString(word)) : null, address)); } } // addr-spec else { if (CheckEmail(word)) { retVal.Add(new Mail_t_Mailbox(null, word)); } } // We have more addresses. if (r.Peek(true) == ',') { r.Char(false); } } return(retVal); }
/// <summary> /// Parses header field from the specified value. /// </summary> /// <param name="value">Header field value. Header field name must be included. For example: 'Return-Path: <[email protected]>'.</param> /// <returns>Returns parsed header field.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception> /// <exception cref="ParseException">Is raised when header field parsing errors.</exception> public static Mail_h_ReturnPath Parse(string value) { if (value == null) { throw new ArgumentNullException("value"); } string[] name_value = value.Split(new[] {':'}, 2); if (name_value.Length != 2) { throw new ParseException("Invalid header field value '" + value + "'."); } Mail_h_ReturnPath retVal = new Mail_h_ReturnPath(null); MIME_Reader r = new MIME_Reader(name_value[1]); r.ToFirstChar(); // Return-Path missing <>, some server won't be honor RFC. if (!r.StartsWith("<")) { retVal.m_Address = r.ToEnd(); } else { retVal.m_Address = r.ReadParenthesized(); } return retVal; }