/// <summary> /// Parses headers from message or mime entry. /// </summary> /// <param name="entryStrm">Stream from where to read headers.</param> /// <returns>Returns header lines.</returns> public static string ParseHeaders(Stream entryStrm) { /*3.1. GENERAL DESCRIPTION * A message consists of header fields and, optionally, a body. * The body is simply a sequence of lines containing ASCII charac- * ters. It is separated from the headers by a null line (i.e., a * line with nothing preceding the CRLF). */ byte[] crlf = new byte[] { (byte)'\r', (byte)'\n' }; MemoryStream msHeaders = new MemoryStream(); StreamHelper r = new StreamHelper(entryStrm, null); byte[] lineData = r.ReadLine(); while (lineData != null) { if (lineData.Length == 0) { break; } msHeaders.Write(lineData, 0, lineData.Length); msHeaders.Write(crlf, 0, crlf.Length); lineData = r.ReadLine(); } return(System.Text.Encoding.Default.GetString(msHeaders.ToArray())); }
/// <summary> /// 接收SMTP服务器回应 /// </summary> private string ReceiveResponse() { var position = 0; StreamHelper.ReadLine(this.stream, this.receiveBuffer, ref position); if (position == 0) { return(""); } // var line = Encoding.ASCII.GetString(this.receiveBuffer, 0, position); if (this.logWriter != null && this.logWriter.Enable) { this.logWriter.WriteTimeLine(line); } return(line); //var read = this.stream.Read(this.receiveBuffer, 0, this.receiveBuffer.Length); //if (read == 0) // return ""; //var receive = Encoding.ASCII.GetString(this.receiveBuffer, 0, read); //if (this.logWriter != null && this.logWriter.Enable) //{ // this.logWriter.WriteTimeLine(receive); //} //return receive; }
private static string ConstructNonMultiPart(MimeEntry ent, bool bodystructure) { string str = "("; // contentType str += "\"" + ent.ContentType.Split('/')[0] + "\" "; // conentSubType if (ent.ContentType.Split('/').Length == 2) { str += "\"" + ent.ContentType.Split('/')[1].Replace(";", "") + "\" "; } else { str += "NIL "; } // conentTypeSubFields string longContentType = MimeParser.ParseHeaderField("Content-Type:", ent.Headers); if (longContentType.IndexOf(";") > -1) { str += "("; string[] fields = longContentType.Split(';'); for (int i = 1; i < fields.Length; i++) { string[] nameValue = fields[i].Replace("\"", "").Trim().Split(new char[] { '=' }, 2); str += "\"" + nameValue[0] + "\" \"" + nameValue[1] + "\""; if (i < fields.Length - 1) { str += " "; } } str += ") "; } else { // if content is attachment and content type name filed is missing, use filename for it string fileName = MimeParser.ParseHeaderFiledSubField("Content-Disposition:", "filename", ent.Headers); if (fileName.Length > 0) { str += "(\"name\" \"" + fileName + "\") "; } else { str += "NIL "; } } // contentID string contentID = MimeParser.ParseHeaderField("Content-ID:", ent.Headers); if (contentID.Length > 0) { str += "\"" + contentID + "\" "; } else { str += "NIL "; } // contentDescription string contentDescription = MimeParser.ParseHeaderField("Content-Description:", ent.Headers); if (contentDescription.Length > 0) { str += "\"" + contentDescription + "\" "; } else { str += "NIL "; } // contentEncoding str += "\"" + ent.ContentEncoding + "\" "; // contentSize str += ent.DataNonDecoded.Length + " "; // envelope NOTE: included only if contentType = "message" !!! // contentLines NOTE: included only if contentType = "text" !!! if (ent.ContentType.ToLower().IndexOf("text") > -1) { StreamHelper r = new StreamHelper(new MemoryStream(ent.DataNonDecoded), null); int nLines = 0; byte[] line = new byte[0]; while (line != null) { line = r.ReadLine(); nLines++; } str += nLines; } // Need to add extended fields if (bodystructure) { str += " "; // md5 str += "NIL "; // contentDisposition string contDispos = MimeParser.ParseHeaderField("Content-Disposition:", ent.Headers); if (contDispos.Length > 0) { str += "("; string[] fields = contDispos.Split(';'); str += "\"" + fields[0] + "\" "; if (fields.Length > 1) { str += "("; for (int i = 1; i < fields.Length; i++) { string[] nameValue = fields[i].Replace("\"", "").Trim().Split(new char[] { '=' }, 2); str += "\"" + nameValue[0] + "\" \"" + nameValue[1] + "\""; if (i < fields.Length - 1) { str += " "; } } str += ")"; } else { str += "NIL"; } str += ") "; } else { str += "NIL "; } // contentLanguage str += "NIL"; } str += ")"; return(str); }
/// <summary> /// Parses headers from message or mime entry. /// </summary> /// <param name="entryStrm">Stream from where to read headers.</param> /// <returns>Returns header lines.</returns> public static string ParseHeaders(Stream entryStrm) { /*3.1. GENERAL DESCRIPTION A message consists of header fields and, optionally, a body. The body is simply a sequence of lines containing ASCII charac- ters. It is separated from the headers by a null line (i.e., a line with nothing preceding the CRLF). */ byte[] crlf = new byte[] { (byte)'\r', (byte)'\n' }; MemoryStream msHeaders = new MemoryStream(); StreamHelper r = new StreamHelper(entryStrm, null); byte[] lineData = r.ReadLine(); while (lineData != null) { if (lineData.Length == 0) { break; } msHeaders.Write(lineData, 0, lineData.Length); msHeaders.Write(crlf, 0, crlf.Length); lineData = r.ReadLine(); } return System.Text.Encoding.Default.GetString(msHeaders.ToArray()); }
/// <summary> /// Parses mime entries. /// </summary> /// <param name="msgStrm"></param> /// <param name="pos"></param> /// <param name="boundaryID"></param> internal ArrayList ParseEntries(MemoryStream msgStrm, int pos, string boundaryID) { ArrayList entries = null; // Entries are already parsed if (m_Entries != null) { return m_Entries; } entries = new ArrayList(); // If message doesn't have entries and have 1 entry (simple text message or contains only attachment). if (this.ContentType.ToLower().IndexOf("multipart/") == -1) { entries.Add(new MimeEntry(msgStrm.ToArray(), this)); m_Entries = entries; return m_Entries; } msgStrm.Position = pos; if (boundaryID.Length > 0) { MemoryStream strmEntry = new MemoryStream(); StreamHelper reader = new StreamHelper(msgStrm, null); byte[] lineData = reader.ReadLine(); // Search first entry while (lineData != null) { string line = System.Text.Encoding.Default.GetString(lineData); if (line.StartsWith("--" + boundaryID)) { break; } lineData = reader.ReadLine(); } // Start reading entries while (lineData != null) { // Read entry data string line = System.Text.Encoding.Default.GetString(lineData); // Next boundary if (line.StartsWith("--" + boundaryID) && strmEntry.Length > 0) { // Add Entry entries.Add(new MimeEntry(strmEntry.ToArray(), this)); strmEntry.SetLength(0); } else { strmEntry.Write(lineData, 0, lineData.Length); strmEntry.Write(new byte[] { (byte)'\r', (byte)'\n' }, 0, 2); } lineData = reader.ReadLine(); } } return entries; }
private void Helo() { this.CheckError("220", "Connect"); //与服务器连接成功 //Dialog("EHLO " + Dns.GetHostName() + MailCommon.NewLine, "250"); //250 : 操作完成 //尝试登录服务器成功 //220 newmx16.qq.com MX QQ Mail Server //ehlo aa //250-newmx16.qq.com //250-SIZE 73400320 //250-STARTTLS //250 OK var esmtpHelo = string.IsNullOrEmpty(this.UserName) ? "HELO " : "EHLO "; //var input = "EHLO " + Dns.GetHostName() + MailCommon.NewLine; var input = ""; if (string.IsNullOrEmpty(this.selfHost)) { input = esmtpHelo + Dns.GetHostName() + MailCommon.NewLine; } else { input = esmtpHelo + this.selfHost + MailCommon.NewLine; } this.Write(input); //reset max size this.maxSize = 0; //read response bool tls = false; long size = 0; while (true) { var position = 0; StreamHelper.ReadLine(this.stream, this.receiveBuffer, ref position); if (position == 0) { throw new IOException("connection is closed from HELO/EHLO"); } // var line = Encoding.ASCII.GetString(this.receiveBuffer, 0, position); // if (this.logWriter != null && this.logWriter.Enable) { this.logWriter.WriteTimeLine(line); } // var head = line.Substring(0, 4); if (head == "250 ") { break; } else if (head != "250-") { throw new SmtpException(line); } else if (line == "250-STARTTLS") { tls = this.enableSSL == false && this.enableTLS == true; } else if (line.StartsWith("250-SIZE ")) { var items = line.Split(' '); if (items.Length == 2) { if (long.TryParse(items[1], out size)) { this.maxSize = size; } } } } if (tls == true && this.stream is SslStream == false) { this.Dialog("STARTTLS\r\n", "220", "STARTTLS"); // create ssl stream this.stream = new SslStream(this.stream, false); // authenticate ssl stream ((SslStream)this.stream).AuthenticateAsClient(this.host, new X509CertificateCollection(), System.Security.Authentication.SslProtocols.Tls, false); } //判断是否为登录 if (!string.IsNullOrEmpty(this.UserName) && !string.IsNullOrEmpty(this.Password)) { this.Dialog("AUTH LOGIN\r\n", "334", "AUTH LOGIN"); //334响应验证 //响应服务器的帐户认证 this.Dialog(Convert.ToBase64String(Encoding.ASCII.GetBytes(this.UserName)) + MailCommon.NewLine, "334", "INPUT USERNAME"); this.Dialog(Convert.ToBase64String(Encoding.ASCII.GetBytes(this.Password)) + MailCommon.NewLine, "235", "INPUT PASSWORD"); } }
/// <summary> /// Parses mime entries. /// </summary> /// <param name="msgStrm"></param> /// <param name="pos"></param> /// <param name="boundaryID"></param> internal ArrayList ParseEntries(MemoryStream msgStrm, int pos, string boundaryID) { ArrayList entries = null; // Entries are already parsed if (m_Entries != null) { return(m_Entries); } entries = new ArrayList(); // If message doesn't have entries and have 1 entry (simple text message or contains only attachment). if (this.ContentType.ToLower().IndexOf("multipart/") == -1) { entries.Add(new MimeEntry(msgStrm.ToArray(), this)); m_Entries = entries; return(m_Entries); } msgStrm.Position = pos; if (boundaryID.Length > 0) { MemoryStream strmEntry = new MemoryStream(); StreamHelper reader = new StreamHelper(msgStrm, null); byte[] lineData = reader.ReadLine(); // Search first entry while (lineData != null) { string line = System.Text.Encoding.Default.GetString(lineData); if (line.StartsWith("--" + boundaryID)) { break; } lineData = reader.ReadLine(); } // Start reading entries while (lineData != null) { // Read entry data string line = System.Text.Encoding.Default.GetString(lineData); // Next boundary if (line.StartsWith("--" + boundaryID) && strmEntry.Length > 0) { // Add Entry entries.Add(new MimeEntry(strmEntry.ToArray(), this)); strmEntry.SetLength(0); } else { strmEntry.Write(lineData, 0, lineData.Length); strmEntry.Write(new byte[] { (byte)'\r', (byte)'\n' }, 0, 2); } lineData = reader.ReadLine(); } } return(entries); }
private static string ConstructNonMultiPart(MimeEntry ent,bool bodystructure) { string str = "("; // contentType str += "\"" + ent.ContentType.Split('/')[0] + "\" "; // conentSubType if(ent.ContentType.Split('/').Length == 2){ str += "\"" + ent.ContentType.Split('/')[1].Replace(";","") + "\" "; } else{ str += "NIL "; } // conentTypeSubFields string longContentType = MimeParser.ParseHeaderField("Content-Type:",ent.Headers); if(longContentType.IndexOf(";") > -1){ str += "("; string[] fields = longContentType.Split(';'); for(int i=1;i<fields.Length;i++){ string[] nameValue = fields[i].Replace("\"","").Trim().Split(new char[]{'='},2); str += "\"" + nameValue[0] + "\" \"" + nameValue[1] + "\""; if(i < fields.Length - 1){ str += " "; } } str += ") "; } else{ // if content is attachment and content type name filed is missing, use filename for it string fileName = MimeParser.ParseHeaderFiledSubField("Content-Disposition:","filename",ent.Headers); if(fileName.Length > 0){ str += "(\"name\" \"" + fileName + "\") "; } else{ str += "NIL "; } } // contentID string contentID = MimeParser.ParseHeaderField("Content-ID:",ent.Headers); if(contentID.Length > 0){ str += "\"" + contentID + "\" "; } else{ str += "NIL "; } // contentDescription string contentDescription = MimeParser.ParseHeaderField("Content-Description:",ent.Headers); if(contentDescription.Length > 0){ str += "\"" + contentDescription + "\" "; } else{ str += "NIL "; } // contentEncoding str += "\"" + ent.ContentEncoding + "\" "; // contentSize str += ent.DataNonDecoded.Length + " "; // envelope NOTE: included only if contentType = "message" !!! // contentLines NOTE: included only if contentType = "text" !!! if(ent.ContentType.ToLower().IndexOf("text") > -1){ StreamHelper r = new StreamHelper(new MemoryStream(ent.DataNonDecoded), null); int nLines = 0; byte[] line = new byte[0]; while(line != null){ line = r.ReadLine(); nLines++; } str += nLines; } // Need to add extended fields if(bodystructure){ str += " "; // md5 str += "NIL "; // contentDisposition string contDispos = MimeParser.ParseHeaderField("Content-Disposition:",ent.Headers); if(contDispos.Length > 0){ str += "("; string[] fields = contDispos.Split(';'); str += "\"" + fields[0] + "\" "; if(fields.Length > 1){ str += "("; for(int i=1;i<fields.Length;i++){ string[] nameValue = fields[i].Replace("\"","").Trim().Split(new char[]{'='},2); str += "\"" + nameValue[0] + "\" \"" + nameValue[1] + "\""; if(i < fields.Length - 1){ str += " "; } } str += ")"; } else{ str += "NIL"; } str += ") "; } else{ str += "NIL "; } // contentLanguage str += "NIL"; } str += ")"; return str; }