public HeaderInfo(System.Collections.Specialized.HybridDictionary headers) { this.TopLevelMediaType = new MimeTopLevelMediaType(); this.Enc = null; try { this.ContentType = MimeTools.parseHeaderFieldBody("Content-Type", headers["Content-Type"].ToString()); this.TopLevelMediaType = (MimeTopLevelMediaType)System.Enum.Parse(TopLevelMediaType.GetType(), this.ContentType["Content-Type"].Split('/')[0], true); this.Subtype = this.ContentType["Content-Type"].Split('/')[1]; this.Enc = MimeTools.parseCharSet(this.ContentType["charset"]); } catch (System.Exception) { this.Enc = default_encoding; this.ContentType = MimeTools.parseHeaderFieldBody("Content-Type", System.String.Concat("text/plain; charset=", this.Enc.BodyName)); this.TopLevelMediaType = MimeTopLevelMediaType.text; this.Subtype = "plain"; } if (this.Enc == null) { this.Enc = default_encoding; } // TODO: rework this try { this.ContentdisPosition = MimeTools.parseHeaderFieldBody("Content-Disposition", headers["Content-Disposition"].ToString()); } catch (System.Exception) { this.ContentdisPosition = new System.Collections.Specialized.StringDictionary(); } try { this.ContentLocation = MimeTools.parseHeaderFieldBody("Content-Location", headers["Content-Location"].ToString()); } catch (System.Exception) { this.ContentLocation = new System.Collections.Specialized.StringDictionary(); } }
/// <summary> /// Parse a rfc 2822 header field with parameters /// </summary> /// <param name="field">field name</param> /// <param name="fieldbody">field body to parse</param> /// <returns>A <see cref="System.Collections.Specialized.StringDictionary" /> from the parsed field body</returns> public static System.Collections.Specialized.StringDictionary parseHeaderFieldBody(System.String field, System.String fieldbody) { if (fieldbody == null) { return(null); } // FIXME: rewrite parseHeaderFieldBody to being regexp based. fieldbody = MimeTools.uncommentString(fieldbody); System.Collections.Specialized.StringDictionary fieldbodycol = new System.Collections.Specialized.StringDictionary(); System.String[] words = fieldbody.Split(new Char[] { ';' }); if (words.Length > 0) { fieldbodycol.Add(field.ToLower(), words[0].ToLower()); for (int i = 1; i < words.Length; i++) { System.String[] param = words[i].Trim(new Char[] { ' ', '\t' }).Split(new Char[] { '=' }, 2); if (param.Length == 2) { param[0] = param[0].Trim(new Char[] { ' ', '\t' }); param[1] = param[1].Trim(new Char[] { ' ', '\t' }); if (param[1].StartsWith("\"") && !param[1].EndsWith("\"")) { do { param[1] += ";" + words[++i]; } while (!words[i].EndsWith("\"") && i < words.Length); } fieldbodycol.Add(param[0], MimeTools.parserfc2047Header(param[1].TrimEnd(';').Trim('\"'))); } } } return(fieldbodycol); }
/// <summary> /// Decode rfc 2047 definition of quoted-printable /// </summary> /// <param name="charset">charset to use when decoding</param> /// <param name="orig"><c>string</c> to decode</param> /// <returns>the decoded <see cref="System.String" /></returns> public static System.String QuotedPrintable2Unicode(System.String charset, System.String orig) { System.Text.Encoding enc = MimeTools.parseCharSet(charset); if (enc == null || orig == null) { return(orig); } MimeTools.QuotedPrintable2Unicode(enc, ref orig); return(orig); }
/// <summary> /// Parse a rfc 2822 date and time specification. rfc 2822 section 3.3 /// </summary> /// <param name="date">rfc 2822 date-time</param> /// <returns>A <see cref="System.DateTime" /> from the parsed header body</returns> public static System.DateTime parseDate(System.String date) { if (date == null || date.Equals(System.String.Empty)) { return(System.DateTime.MinValue); } System.DateTime msgDateTime; date = MimeTools.uncommentString(date); msgDateTime = new System.DateTime(0); try { // TODO: Complete the list date = date.Replace("UT", "+0000"); date = date.Replace("GMT", "+0000"); date = date.Replace("EDT", "-0400"); date = date.Replace("EST", "-0500"); date = date.Replace("CDT", "-0500"); date = date.Replace("MDT", "-0600"); date = date.Replace("MST", "-0600"); date = date.Replace("EST", "-0700"); date = date.Replace("PDT", "-0700"); date = date.Replace("PST", "-0800"); date = date.Replace("AM", System.String.Empty); date = date.Replace("PM", System.String.Empty); int rpos = date.LastIndexOfAny(new Char[] { ' ', '\t' }); if (rpos > 0 && rpos != date.Length - 6) { date = date.Substring(0, rpos + 1) + "-0000"; } date = date.Insert(date.Length - 2, ":"); msgDateTime = DateTime.ParseExact(date, _date_formats, System.Globalization.CultureInfo.CreateSpecificCulture("en-us"), System.Globalization.DateTimeStyles.AllowInnerWhite); #if LOG } catch (System.Exception e) { if (log.IsErrorEnabled) { log.Error(System.String.Concat("Error parsing date: [", date, "]"), e); } #else } catch (System.Exception) { #endif msgDateTime = new System.DateTime(0); } return(msgDateTime); }
/// <summary> /// Returns the requested header field body. /// </summary> /// <param name="name">Header field name</param> /// <param name="defaultvalue">Value to return when the requested field is not present</param> /// <param name="uncomment"><b>true</b> to uncomment using <see cref="MimeTools.uncommentString" />; <b>false</b> to return the value unchanged.</param> /// <param name="rfc2047decode"><b>true</b> to decode <see cref="MimeTools.rfc2047decode" />; <b>false</b> to return the value unchanged.</param> /// <returns>Header field body</returns> public System.String GetHeaderField(System.String name, System.String defaultvalue, bool uncomment, bool rfc2047decode) { System.String tmp = this.GetProperty(name); if (tmp == null) { tmp = defaultvalue; } else { if (uncomment) { tmp = MimeTools.uncommentString(tmp); } if (rfc2047decode) { tmp = MimeTools.rfc2047decode(tmp); } } return(tmp); }
/// <summary> /// Parse a rfc 2822 name-address specification. rfc 2822 section 3.4 /// </summary> /// <param name="from">address</param> /// <param name="part">1 is display-name; 2 is addr-spec</param> /// <returns>the requested <see cref="System.String" /></returns> public static System.String parseFrom(System.String from, int part) { int pos; if (from == null || from.Length < 1) { return(System.String.Empty); } switch (part) { case 1: pos = from.LastIndexOf('<'); pos = (pos < 0)?from.Length:pos; from = from.Substring(0, pos).Trim(); from = MimeTools.parserfc2047Header(from); return(from); case 2: pos = from.LastIndexOf('<') + 1; return(from.Substring(pos, from.Length - pos).Trim(new char[] { '<', '>', ' ' })); } return(from); }
/// <summary> /// Dumps the body of this entity into a file /// </summary> /// <param name="path">path of the destination folder</param> /// <param name="name">name of the file</param> /// <returns><see cref="System.IO.FileInfo" /> that represents the file where the body has been saved</returns> public System.IO.FileInfo DumpBody(System.String path, System.String name) { System.IO.FileInfo file = null; if (name != null) { name = System.IO.Path.GetFileName(name); // Dump file contents try { System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(path); dir.Create(); try { file = new System.IO.FileInfo(System.IO.Path.Combine(path, name)); } catch (System.ArgumentException exception) { file = null; throw new Exception( System.String.Concat("Filename [", System.IO.Path.Combine(path, name), "] is not allowed by the filesystem"), exception); } if (dir.Exists) { if (dir.FullName.Equals(new System.IO.DirectoryInfo(file.Directory.FullName).FullName)) { if (!file.Exists) { System.IO.Stream stream; try { stream = file.Create(); } catch (System.Exception e) { throw new Exception(System.String.Concat("Error creating file [", file.FullName, "]"), e); } try { this.DumpBody(stream); } catch (Exception) { throw new Exception(System.String.Concat("Error writting file [", file.FullName, "] to disk")); } stream.Close(); // The file should be there file.Refresh(); // Set file dates if (this.Header.ContentDispositionParameters.ContainsKey("creation-date")) { file.CreationTime = MimeTools.parseDate(this.Header.ContentDispositionParameters["creation-date"]); } if (this.Header.ContentDispositionParameters.ContainsKey("modification-date")) { file.LastWriteTime = MimeTools.parseDate(this.Header.ContentDispositionParameters["modification-date"]); } if (this.Header.ContentDispositionParameters.ContainsKey("read-date")) { file.LastAccessTime = MimeTools.parseDate(this.Header.ContentDispositionParameters["read-date"]); } } else { System.Console.WriteLine("File already exists, skipping."); } } } } catch (System.Exception) { if (file != null) { file.Refresh(); if (file.Exists) { file.Delete(); } } file = null; } } return(file); }
/// <summary> /// Initializes a new address from a RFC 2822 name-addr specification string /// </summary> /// <param name="dir">RFC 2822 name-addr address</param> /// public MimeAddress(System.String dir) { _name = MimeTools.parseFrom(dir, 1); _address = MimeTools.parseFrom(dir, 2); }
/// <summary> /// rfc 2047 header body decoding /// </summary> /// <param name="word"><c>string</c> to decode</param> /// <returns>the decoded <see cref="System.String" /></returns> public static System.String rfc2047decode(System.String word) { System.String[] words; System.String[] wordetails; System.Text.RegularExpressions.Regex rfc2047format = new System.Text.RegularExpressions.Regex(@"(=\?[\-a-zA-Z0-9]+\?[qQbB]\?[a-zA-Z0-9=_\-\.$%&/\'\\!:;{}\+\*\|@#~`^]+\?=)\s*", System.Text.RegularExpressions.RegexOptions.ECMAScript); // No rfc2047 format if (!rfc2047format.IsMatch(word)) { #if LOG if (log.IsDebugEnabled) { log.Debug("Not a RFC 2047 string: " + word); } #endif return(word); } #if LOG if (log.IsDebugEnabled) { log.Debug("Decoding 2047 string: " + word); } #endif words = rfc2047format.Split(word); word = System.String.Empty; rfc2047format = new System.Text.RegularExpressions.Regex(@"=\?([\-a-zA-Z0-9]+)\?([qQbB])\?([a-zA-Z0-9=_\-\.$%&/\'\\!:;{}\+\*\|@#~`^]+)\?=", System.Text.RegularExpressions.RegexOptions.ECMAScript); for (int i = 0; i < words.GetLength(0); i++) { if (!rfc2047format.IsMatch(words[i])) { word += words[i]; continue; } wordetails = rfc2047format.Split(words[i]); switch (wordetails[2]) { case "q": case "Q": word += MimeTools.QuotedPrintable2Unicode(wordetails[1], wordetails[3]).Replace('_', ' ');; break; case "b": case "B": try { System.Text.Encoding enc = System.Text.Encoding.GetEncoding(wordetails[1]); System.Byte[] ch = System.Convert.FromBase64String(wordetails[3]); word += enc.GetString(ch); } catch (System.Exception) { } break; } } #if LOG if (log.IsDebugEnabled) { log.Debug("Decoded 2047 string: " + word); } #endif return(word); }
/// <summary> /// Parse and decode rfc 2047 header body /// </summary> /// <param name="header">header body to parse</param> /// <returns>parsed <see cref="System.String" /></returns> public static System.String parserfc2047Header(System.String header) { header = header.Replace("\"", System.String.Empty); header = MimeTools.rfc2047decode(header); return(header); }