public DataParseStatus ParseHeaders(byte[] buffer, int size, ref int unparsed) { int headerKeyBegin = -1; int hederKeyEnd = -1; int finalCLRNCount = -1; int currIndex = unparsed; Encoding defaultEncoding = Encoding.Default; do { string strHeader = String.Empty; bool flag1 = false; bool isHeaderKeyUTF8 = false; bool isHeaderValueUTF8 = false; string strHeaderValue = null; if (base.Count == 0) { while (currIndex < size && (buffer[currIndex] == 32 || /*[space]*/ buffer[currIndex] == 9)) { currIndex++; } if (currIndex == size) { return(DataParseStatus.NeedMoreData); } } headerKeyBegin = currIndex; for (; currIndex < size && buffer[currIndex] != 58 /*:*/ && buffer[currIndex] != 10; currIndex++) { if (buffer[currIndex] > 32 /*[space]*/) { hederKeyEnd = currIndex; //isHeaderKeyUTF8 = !isHeaderKeyUTF8 ? (buffer[currIndex] > 127) : true; } } if (currIndex == size) { return(DataParseStatus.NeedMoreData); } while (true) { string strHeaderValueTmp = String.Empty; int headerValueBegin = -1; int headerValueEnd = -1; for (finalCLRNCount = (base.Count != 0 || hederKeyEnd >= 0) ? 0 : 1; currIndex < size && finalCLRNCount < 2 && (buffer[currIndex] <= 32 /*[space]*/ || buffer[currIndex] == 58); currIndex++) { if (buffer[currIndex] == 10) { finalCLRNCount++; flag1 = (currIndex + 1 < size) ? ((buffer[currIndex + 1] != 32 /*[space]*/) ? (buffer[currIndex + 1] == 9) : true) : false; } } if (finalCLRNCount != 2 && (finalCLRNCount != 1 || flag1)) { if (currIndex == size) { return(DataParseStatus.NeedMoreData); } headerValueBegin = currIndex; for (; currIndex < size && buffer[currIndex] != 10; currIndex++) { if (buffer[currIndex] > 32 /*[space]*/) { headerValueEnd = currIndex; //isHeaderValueUTF8 = !isHeaderValueUTF8 ? (buffer[currIndex] > 127) : true; } } if (currIndex == size) { return(DataParseStatus.NeedMoreData); } for (finalCLRNCount = 0; currIndex < size && finalCLRNCount < 2 && (buffer[currIndex] == 13 || buffer[currIndex] == 10); currIndex++) { if (buffer[currIndex] == 10) { finalCLRNCount++; } } if (currIndex == size && finalCLRNCount < 2) { return(DataParseStatus.NeedMoreData); } } if (headerValueBegin >= 0 && headerValueBegin > hederKeyEnd && headerValueEnd >= headerValueBegin) { if (isHeaderValueUTF8) { strHeaderValueTmp = Encoding.UTF8.GetString(buffer, headerValueBegin, headerValueEnd - headerValueBegin + 1); } else { strHeaderValueTmp = defaultEncoding.GetString(buffer, headerValueBegin, headerValueEnd - headerValueBegin + 1); } } strHeaderValue = (strHeaderValue != null) ? String.Concat(strHeaderValue, " ", strHeaderValueTmp) : strHeaderValueTmp; if (currIndex >= size || finalCLRNCount != 1 || buffer[currIndex] != 32 /*[space]*/ && buffer[currIndex] != 9) { break; } currIndex++; } if (headerKeyBegin >= 0 && hederKeyEnd >= headerKeyBegin) { if (isHeaderKeyUTF8) { strHeader = Encoding.UTF8.GetString(buffer, headerKeyBegin, hederKeyEnd - headerKeyBegin + 1); } else { strHeader = Encoding.ASCII.GetString(buffer, headerKeyBegin, hederKeyEnd - headerKeyBegin + 1); } } if (strHeader.Length > 0) { string strValue = DeocodeHeaderValue(strHeaderValue); base.Add(strHeader, strValue); if (strHeader == "Content-Type") { string strContentType; Hashtable parametrs; MimeEntry.ParseHeader(strValue, out strContentType, out parametrs); string strCharset = (string)parametrs["charset"]; if (!string.IsNullOrEmpty(strCharset)) { try { defaultEncoding = Encoding.GetEncoding(strCharset); } catch { defaultEncoding = Encoding.Default; } } } } unparsed = currIndex; }while (finalCLRNCount != 2); //this.IsReadOnly = true; return(DataParseStatus.Done); }
protected virtual void ParseBody() { string strFullConentType = _headers["Content-Type"]; if (strFullConentType == null) { strFullConentType = ""; } //string strContentTypeValue = null; Hashtable parametrs; MimeEntry.ParseHeader(strFullConentType, out _contentType, out parametrs); // Step 2. Parse Messagy Body [1/23/2004] if (!_contentType.StartsWith("multipart/")) { _charSet = (string)parametrs["charset"]; if (_charSet == null) { _charSet = Encoding.Default.HeaderName; } string ContentEncoding = _headers["Content-Transfer-Encoding"]; if (ContentEncoding == null) { ContentEncoding = "8bit"; } string strDisposition = _headers["Content-Disposition"]; if (strDisposition != null) { Hashtable DispositionParameters; string DispositionType; MimeEntry.ParseHeader(strDisposition, out DispositionType, out DispositionParameters); DispositionType = DispositionType.ToLower(); if (DispositionType == "attachment") { this._disposition = Disposition.Attachment; } else if (DispositionType == "inline") { this._disposition = Disposition.Inline; } _fileName = (string)DispositionParameters["filename"]; if (_fileName != null) { _fileName = Rfc822HeaderCollection.DeocodeHeaderValue(_fileName); } } //string BodyString = Encoding.Default.GetString(this._BinaryData.GetBuffer(),this._BodyOffset,(int)(this._BinaryData.Length - this._BodyOffset)); Encoding encoding = null; try { encoding = Encoding.GetEncoding(CharSet); } catch { encoding = Encoding.Default; } string BodyString = encoding.GetString(this._BinaryData.GetBuffer(), this._BodyOffset, (int)(this._BinaryData.Length - this._BodyOffset)); //string BodyString = Encoding.ASCII.GetString(this._BinaryData.GetBuffer(),this._BodyOffset,(int)(this._BinaryData.Length - this._BodyOffset)); //string BodyString2 = Encoding.UTF8.GetString(this._BinaryData.GetBuffer(),this._BodyOffset,(int)(this._BinaryData.Length - this._BodyOffset)); switch (ContentEncoding.ToLower()) { case "quoted-printable": _body = encoding.GetBytes(MimeEntry.QDecode(encoding, BodyString)); break; case "7bit": //_body = Encoding.ASCII.GetBytes(BodyString); _body = encoding.GetBytes(BodyString); break; default: case "8bit": _body = encoding.GetBytes(BodyString); break; case "base64": BodyString = BodyString.Trim(); if (BodyString.Length > 0) { int base64FixCount = 0; // Fix If Base 64 is broken while (true) { try { _body = Convert.FromBase64String(BodyString); break; } catch (System.FormatException) { // Remove not supported chars if (base64FixCount == 0) { BodyString = Regex.Replace(BodyString, "[^a-zA-Z0-9+/=]+", string.Empty); } else if (base64FixCount == 1) { BodyString += "="; } else { BodyString = BodyString.Substring(0, BodyString.Length - 1); } if (BodyString.Length == 0 || base64FixCount == 25) // Max 25 Attempts to fix chars { _body = new byte[] { }; break; } base64FixCount++; } } } else { _body = new byte[] {} }; break; case "binary": _body = encoding.GetBytes(BodyString); break; //default: // throw new Pop3ServerIncorectEMailFormatException("Not supported content-encoding " + ContentEncoding + " !"); } } else { DataParseStatus parseStatus = _mimeEntries.ParseMimeEntries(_BinaryData.GetBuffer(), (int)_BinaryData.Length, ref _BodyOffset, this.Headers); } }
internal DataParseStatus ParseMimeEntries(byte[] buffer, int size, ref int unparsed, Rfc822HeaderCollection headers) { string strFullConentType = headers["Content-Type"]; if (strFullConentType == null) { strFullConentType = ""; } string strContentTypeValue = null; Hashtable parametrs; MimeEntry.ParseHeader(strFullConentType, out strContentTypeValue, out parametrs); if (!strContentTypeValue.StartsWith("multipart/", true, CultureInfo.InvariantCulture)) { // Simple Email [1/27/2004] MemoryStream strmEntry = new MemoryStream(); strmEntry.Write(buffer, unparsed, size - unparsed); this.Add(new MimeEntry(strmEntry, headers)); } else { // Parse Multipart Value string boundaryID = (string)parametrs["boundary"]; // Step 1. Unpack multipart [2/10/2004] StreamLineReader lineReader = new StreamLineReader(buffer, unparsed, size); byte[] lineData = lineReader.ReadLine(); // Step 1.1 Search first entry while (lineData != null) { string strLine = System.Text.Encoding.Default.GetString(lineData); if (strLine.StartsWith("--" + boundaryID)) { lineData = lineReader.ReadLine(); break; } lineData = lineReader.ReadLine(); } // Step 1.2 Start reading entries MemoryStream strmEntry = new MemoryStream(); while (lineData != null) { string strLine = System.Text.Encoding.Default.GetString(lineData); if (strLine.StartsWith("--" + boundaryID) && strmEntry.Length > 0) { // Step 1.3 Add Entry try { MimeEntry newEntry = new MimeEntry(strmEntry); this.Add(newEntry); } catch (Pop3ServerIncorectEMailFormatException ex) { // Skeep Broken Entry if (ex.InnerException != null) { throw; } } strmEntry.SetLength(0); } else { strmEntry.Write(lineData, 0, lineData.Length); strmEntry.Write(new byte[] { (byte)'\r', (byte)'\n' }, 0, 2); } lineData = lineReader.ReadLine(); } } return(DataParseStatus.Done); }