/// <summary> /// Initializes a new instance of the <see cref="MailKit.Security.SaslMechanismLogin"/> class. /// </summary> /// <remarks> /// Creates a new LOGIN SASL context. /// </remarks> /// <param name="uri">The URI of the service.</param> /// <param name="encoding">The encoding to use for the user's credentials.</param> /// <param name="credentials">The user's credentials.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="uri"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="credentials"/> is <c>null</c>.</para> /// </exception> public SaslMechanismLogin (Uri uri, Encoding encoding, ICredentials credentials) : base (uri, credentials) { if (encoding == null) throw new ArgumentNullException (nameof (encoding)); this.encoding = encoding; }
public Pop3Command (CancellationToken cancellationToken, Pop3CommandHandler handler, Encoding encoding, string format, params object[] args) { Command = string.Format (format, args); CancellationToken = cancellationToken; Encoding = encoding; Handler = handler; }
static SaslMechanismDigestMd5() { try { Latin1 = Encoding.GetEncoding(28591); } catch (NotSupportedException) { Latin1 = Encoding.GetEncoding(1252); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.InternetAddress"/> class. /// </summary> /// <remarks> /// Initializes the <see cref="Encoding"/> and <see cref="Name"/> properties of the internet address. /// </remarks> /// <param name="encoding">The character encoding to be used for encoding the name.</param> /// <param name="name">The name of the mailbox or group.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="encoding"/> is <c>null</c>. /// </exception> protected InternetAddress(Encoding encoding, string name) { if (encoding == null) throw new ArgumentNullException ("encoding"); Encoding = encoding; Name = name; }
/// <summary> /// Initializes a new instance of the <see cref="MailKit.Security.SaslMechanismLogin"/> class. /// </summary> /// <remarks> /// Creates a new LOGIN SASL context. /// </remarks> /// <param name="encoding">The encoding to use for the user's credentials.</param> /// <param name="credentials">The user's credentials.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="credentials"/> is <c>null</c>.</para> /// </exception> public SaslMechanismLogin(Encoding encoding, NetworkCredential credentials) : base(credentials) { if (encoding == null) { throw new ArgumentNullException(nameof(encoding)); } this.encoding = encoding; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.ParserOptions"/> class. /// </summary> /// <remarks> /// By default, new instances of <see cref="ParserOptions"/> enable rfc2047 work-arounds /// (which are needed for maximum interoperability with mail software used in the wild) /// and do not respect the Content-Length header value. /// </remarks> public ParserOptions() { AddressParserComplianceMode = RfcComplianceMode.Loose; ParameterComplianceMode = RfcComplianceMode.Loose; Rfc2047ComplianceMode = RfcComplianceMode.Loose; CharsetEncoding = CharsetUtils.UTF8; AllowAddressesWithoutDomain = false; RespectContentLength = false; }
/// <summary> /// Initializes a new instance of the <see cref="MailKit.Security.SaslMechanismLogin"/> class. /// </summary> /// <remarks> /// Creates a new LOGIN SASL context. /// </remarks> /// <param name="encoding">The encoding to use for the user's credentials.</param> /// <param name="userName">The user name.</param> /// <param name="password">The password.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="userName"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="password"/> is <c>null</c>.</para> /// </exception> public SaslMechanismLogin(Encoding encoding, string userName, string password) : base(userName, password) { if (encoding == null) { throw new ArgumentNullException(nameof(encoding)); } this.encoding = encoding; }
public SaslMechanismLogin(Uri uri, Encoding encoding, ICredentials credentials) : base(uri, credentials) { if (encoding == null) { throw new ArgumentNullException(nameof(encoding)); } this.encoding = encoding; }
static bool ProbeCharset(int codepage) { try { Encoding.GetEncoding(codepage); return(true); } catch { return(false); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MailboxAddress"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MailboxAddress"/> with the specified name, address and route. The /// specified text encoding is used when encoding the name according to the rules of rfc2047. /// </remarks> /// <param name="encoding">The character encoding to be used for encoding the name.</param> /// <param name="name">The name of the mailbox.</param> /// <param name="route">The route of the mailbox.</param> /// <param name="address">The address of the mailbox.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="route"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="address"/> is <c>null</c>.</para> /// </exception> public MailboxAddress (Encoding encoding, string name, IEnumerable<string> route, string address) : base (encoding, name) { if (address == null) throw new ArgumentNullException ("address"); Route = new DomainList (route); Route.Changed += RouteChanged; Address = address; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Text.HtmlWriter"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="HtmlWriter"/>. /// </remarks> /// <param name="stream">The output stream.</param> /// <param name="encoding">The encoding to use for the output.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// </exception> public HtmlWriter (Stream stream, Encoding encoding) { if (stream == null) throw new ArgumentNullException ("stream"); if (encoding == null) throw new ArgumentNullException ("encoding"); html = new StreamWriter (stream, encoding, 4096); }
static SmtpStream () { UTF8 = Encoding.GetEncoding (65001, new EncoderExceptionFallback (), new DecoderExceptionFallback ()); try { Latin1 = Encoding.GetEncoding (28591); } catch (NotSupportedException) { Latin1 = Encoding.GetEncoding (1252); } }
static SmtpStream() { UTF8 = Encoding.GetEncoding(65001, new EncoderExceptionFallback(), new DecoderExceptionFallback()); try { Latin1 = Encoding.GetEncoding(28591); } catch (NotSupportedException) { Latin1 = Encoding.GetEncoding(1252); } }
internal static char[] ConvertToUnicode(Encoding encoding, byte[] input, int startIndex, int length, out int charCount) { var decoder = encoding.GetDecoder(); int count = decoder.GetCharCount(input, startIndex, length, true); var output = new char[count]; charCount = decoder.GetChars(input, startIndex, length, output, 0, true); return(output); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.InternetAddress"/> class. /// </summary> /// <remarks> /// Initializes the <see cref="Encoding"/> and <see cref="Name"/> properties of the internet address. /// </remarks> /// <param name="encoding">The character encoding to be used for encoding the name.</param> /// <param name="name">The name of the mailbox or group.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="encoding"/> is <c>null</c>. /// </exception> protected InternetAddress(Encoding encoding, string name) { if (encoding == null) { throw new ArgumentNullException("encoding"); } Encoding = encoding; Name = name; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MailboxAddress"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MailboxAddress"/> with the specified name, address and route. The /// specified text encoding is used when encoding the name according to the rules of rfc2047. /// </remarks> /// <param name="encoding">The character encoding to be used for encoding the name.</param> /// <param name="name">The name of the mailbox.</param> /// <param name="route">The route of the mailbox.</param> /// <param name="address">The address of the mailbox.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="route"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="address"/> is <c>null</c>.</para> /// </exception> public MailboxAddress(Encoding encoding, string name, IEnumerable <string> route, string address) : base(encoding, name) { if (address == null) { throw new ArgumentNullException("address"); } Route = new DomainList(route); Route.Changed += RouteChanged; Address = address; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MailboxAddress"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MailboxAddress"/> with the specified name and address. The /// specified text encoding is used when encoding the name according to the rules of rfc2047. /// </remarks> /// <param name="encoding">The character encoding to be used for encoding the name.</param> /// <param name="name">The name of the mailbox.</param> /// <param name="address">The address of the mailbox.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="address"/> is <c>null</c>.</para> /// </exception> /// <exception cref="ParseException"> /// <paramref name="address"/> is malformed. /// </exception> public MailboxAddress(Encoding encoding, string name, string address) : base(encoding, name) { if (address == null) { throw new ArgumentNullException(nameof(address)); } Route = new DomainList(); Route.Changed += RouteChanged; Address = address; }
internal string Encode(FormatOptions options, Encoding charset) { int lineLength = "Content-Disposition: ".Length; var value = new StringBuilder(" "); value.Append(disposition); Parameters.Encode(options, value, ref lineLength, charset); value.Append(options.NewLine); return(value.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.ParserOptions"/> class. /// </summary> /// <remarks> /// By default, new instances of <see cref="ParserOptions"/> enable rfc2047 work-arounds /// (which are needed for maximum interoperability with mail software used in the wild) /// and do not respect the Content-Length header value. /// </remarks> public ParserOptions() { AddressParserComplianceMode = RfcComplianceMode.Loose; ParameterComplianceMode = RfcComplianceMode.Loose; Rfc2047ComplianceMode = RfcComplianceMode.Loose; CharsetEncoding = CharsetUtils.UTF8; AllowUnquotedCommasInAddresses = true; AllowAddressesWithoutDomain = true; RespectContentLength = false; MaxAddressGroupDepth = 3; }
public static Encoding GetEncoding(string charset) { int codepage = GetCodePage(charset); if (codepage == -1) { throw new NotSupportedException(); } return(Encoding.GetEncoding(codepage)); }
internal static char[] ConvertToUnicode(ParserOptions options, byte[] input, int startIndex, int length, out int charCount) { var invalid = new InvalidByteCountFallback(); var userCharset = options.CharsetEncoding; int min = int.MaxValue; int bestCharCount = 0; char[] output = null; Encoding encoding; Decoder decoder; int[] codepages; int best = -1; int count; // Note: 65001 is UTF-8 and 28591 is iso-8859-1 if (userCharset != null && userCharset.CodePage != 65001 && userCharset.CodePage != 28591) { codepages = new [] { 65001, userCharset.CodePage, 28591 }; } else { codepages = new [] { 65001, 28591 }; } for (int i = 0; i < codepages.Length; i++) { encoding = Encoding.GetEncoding(codepages[i], new EncoderReplacementFallback("?"), invalid); decoder = (Decoder)encoding.GetDecoder(); count = decoder.GetCharCount(input, startIndex, length, true); if (invalid.InvalidByteCount < min) { min = invalid.InvalidByteCount; bestCharCount = count; best = codepages[i]; if (min == 0) { break; } } invalid.Reset(); } encoding = GetEncoding(best, "?"); decoder = (Decoder)encoding.GetDecoder(); output = new char[bestCharCount]; charCount = decoder.GetChars(input, startIndex, length, output, 0, true); return(output); }
static bool TryParseGroup(ParserOptions options, byte[] text, int startIndex, ref int index, int endIndex, string name, int codepage, bool throwOnError, out InternetAddress address) { List <InternetAddress> members; Encoding encoding; try { encoding = Encoding.GetEncoding(codepage); } catch { encoding = Encoding.UTF8; } address = null; // skip over the ':' index++; if (index >= endIndex) { if (throwOnError) { throw new ParseException(string.Format("Incomplete address group at offset {0}", startIndex), startIndex, index); } return(false); } if (InternetAddressList.TryParse(options, text, ref index, endIndex, true, throwOnError, out members)) { address = new GroupAddress(encoding, name, members); } else { address = new GroupAddress(encoding, name); } if (index >= endIndex || text[index] != (byte)';') { if (throwOnError) { throw new ParseException(string.Format("Expected to find ';' at offset {0}", index), startIndex, index); } while (index < endIndex && text[index] != (byte)';') { index++; } } else { index++; } return(true); }
private async void Button_Click(object sender, RoutedEventArgs e) { string uri = @"https://alexeyd.herokuapp.com/mpro5?a=" + a.Text; var client = new HttpClient(); byte[] request = await client.GetByteArrayAsync(new Uri(uri)); Portable.Text.Encoding encoding = Portable.Text.Encoding.GetEncoding(1251); var s = encoding.GetString(request, 0, request.Length); otv.Content = s; }
public static byte[] UrlDecodeToBytes(string str, Encoding e) { if (str == null) { return(null); } if (e == null) { throw new ArgumentNullException("e"); } return(UrlDecodeToBytes(e.GetBytes(str))); }
/// <summary> /// Sets the text content and the charset parameter in the Content-Type header. /// </summary> /// <remarks> /// This method is similar to setting the <see cref="TextPart.Text"/> property, /// but allows specifying a charset encoding to use. Also updates the /// <see cref="ContentType.Charset"/> property. /// </remarks> /// <param name="encoding">The charset encoding.</param> /// <param name="text">The text content.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="text"/> is <c>null</c>.</para> /// </exception> public void SetText (Encoding encoding, string text) { if (encoding == null) throw new ArgumentNullException (nameof (encoding)); if (text == null) throw new ArgumentNullException (nameof (text)); ContentType.Parameters["charset"] = CharsetUtils.GetMimeCharset (encoding); var content = new MemoryStream (encoding.GetBytes (text)); Content = new MimeContent (content); }
public static Encoding GetEncoding(int codepage, string fallback) { if (fallback == null) { throw new ArgumentNullException(nameof(fallback)); } var encoderFallback = new EncoderReplacementFallback(fallback); var decoderFallback = new DecoderReplacementFallback(fallback); return(Encoding.GetEncoding(codepage, encoderFallback, decoderFallback)); }
public static int GetCodePage(string charset) { if (charset == null) { throw new ArgumentNullException(nameof(charset)); } int codepage; lock (aliases) { if (!aliases.TryGetValue(charset, out codepage)) { Encoding encoding; codepage = ParseCodePage(charset); if (codepage == -1) { try { encoding = Encoding.GetEncoding(charset); codepage = encoding.CodePage; if (!aliases.ContainsKey(encoding.WebName)) { aliases[encoding.WebName] = codepage; } } catch { codepage = -1; } } else { try { encoding = Encoding.GetEncoding(codepage); if (!aliases.ContainsKey(encoding.WebName)) { aliases[encoding.WebName] = codepage; } } catch { codepage = -1; } } if (!aliases.ContainsKey(charset)) { aliases[charset] = codepage; } } } return(codepage); }
public static byte[] UrlEncodeToBytes(string str, Encoding e) { if (str == null) { return(null); } if (str.Length == 0) { return(new byte[0]); } byte[] bytes = e.GetBytes(str); return(UrlEncodeToBytes(bytes, 0, bytes.Length)); }
/// <summary> /// Gets the header value using the specified charset. /// </summary> /// <remarks> /// <para>If the raw header value does not properly encode non-ASCII text, the decoder /// will fall back to a default charset encoding. Sometimes, however, this /// default charset fallback is wrong and the mail client may wish to override /// that default charset on a per-header basis.</para> /// <para>By using this method, the client is able to override the fallback charset /// on a per-header basis.</para> /// </remarks> /// <returns>The value.</returns> /// <param name="charset">Charset.</param> public string GetValue(Encoding charset) { if (charset == null) { throw new ArgumentNullException("charset"); } var options = Options.Clone(); options.CharsetEncoding = charset; return(Unfold(Rfc2047.DecodeText(options, RawValue))); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.TextPart"/> /// class with the specified text subtype. /// </summary> /// <remarks> /// <para>Creates a new <see cref="TextPart"/> with the specified subtype.</para> /// <note type="note"><para>Typically the <paramref name="subtype"/> should either be /// <c>"plain"</c> for plain text content or <c>"html"</c> for HTML content.</para> /// <para>For more options, check the MIME-type registry at /// <a href="http://www.iana.org/assignments/media-types/media-types.xhtml#text"> /// http://www.iana.org/assignments/media-types/media-types.xhtml#text /// </a></para></note> /// </remarks> /// <param name="subtype">The media subtype.</param> /// <param name="args">An array of initialization parameters: headers, charset encoding and text.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="subtype"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="args"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// <para><paramref name="args"/> contains more than one <see cref="System.Text.Encoding"/>.</para> /// <para>-or-</para> /// <para><paramref name="args"/> contains more than one <see cref="System.String"/>.</para> /// <para>-or-</para> /// <para><paramref name="args"/> contains one or more arguments of an unknown type.</para> /// </exception> public TextPart(string subtype, params object[] args) : this(subtype) { if (args == null) { throw new ArgumentNullException(nameof(args)); } // Default to UTF8 if not given. Encoding encoding = null; string text = null; foreach (object obj in args) { if (obj == null || TryInit(obj)) { continue; } var enc = obj as Encoding; if (enc != null) { if (encoding != null) { throw new ArgumentException("An encoding should not be specified more than once."); } encoding = enc; continue; } var str = obj as string; if (str != null) { if (text != null) { throw new ArgumentException("The text should not be specified more than once."); } text = str; continue; } throw new ArgumentException("Unknown initialization parameter: " + obj.GetType()); } if (text != null) { encoding = encoding ?? Encoding.UTF8; SetText(encoding, text); } }
private static void WriteCharBytes(IList buf, char ch, Encoding e) { if (ch > '\x00ff') { foreach (byte num in e.GetBytes(new char[] { ch })) { buf.Add(num); } } else { buf.Add((byte)ch); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Text.HtmlWriter"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="HtmlWriter"/>. /// </remarks> /// <param name="stream">The output stream.</param> /// <param name="encoding">The encoding to use for the output.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// </exception> public HtmlWriter(Stream stream, Encoding encoding) { if (stream == null) { throw new ArgumentNullException("stream"); } if (encoding == null) { throw new ArgumentNullException("encoding"); } html = new StreamWriter(stream, encoding, 4096); }
public static Encoding GetEncoding(string charset) { int codepage; if ((codepage = GetCodePage(charset)) == -1) { throw new NotSupportedException(string.Format("The '{0}' encoding is not supported.", charset)); } try { return(Encoding.GetEncoding(codepage)); } catch (Exception ex) { throw new NotSupportedException(string.Format("The '{0}' encoding is not supported.", charset), ex); } }
public static string GetMimeCharset(Encoding encoding) { if (encoding == null) { throw new ArgumentNullException("encoding"); } switch (encoding.CodePage) { case 949: // ks_c_5601-1987 return("euc-kr"); default: return(encoding.HeaderName.ToLowerInvariant()); } }
/// <summary> /// Returns a <see cref="System.String"/> that represents the current <see cref="MimeKit.MimeEntity"/>. /// </summary> /// <remarks> /// Returns a <see cref="System.String"/> that represents the current <see cref="MimeKit.MimeEntity"/>. /// </remarks> /// <returns>A <see cref="System.String"/> that represents the current <see cref="MimeKit.MimeEntity"/>.</returns> public override string ToString() { using (var memory = new MemoryStream()) { WriteTo(memory); var latin1 = Encoding.GetEncoding(28591); #if !PORTABLE var buffer = memory.GetBuffer(); #else var buffer = memory.ToArray(); #endif int count = (int)memory.Length; return(latin1.GetString(buffer, 0, count)); } }
internal string Encode(FormatOptions options, Encoding charset) { int lineLength = "Content-Type:".Length; var value = new StringBuilder(" "); value.Append(MediaType); value.Append('/'); value.Append(MediaSubtype); lineLength += value.Length; Parameters.Encode(options, value, ref lineLength, charset); value.Append(options.NewLine); return(value.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Header"/> class. /// </summary> /// <remarks> /// Creates a new message or entity header for the specified field and /// value pair. The encoding is used to determine which charset to use /// when encoding the value according to the rules of rfc2047. /// </remarks> /// <param name="charset">The charset that should be used to encode the /// header value.</param> /// <param name="id">The header identifier.</param> /// <param name="value">The value of the header.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="charset"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="value"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="id"/> is not a valid <see cref="HeaderId"/>. /// </exception> public Header (Encoding charset, HeaderId id, string value) { if (charset == null) throw new ArgumentNullException ("charset"); if (id == HeaderId.Unknown) throw new ArgumentOutOfRangeException ("id"); if (value == null) throw new ArgumentNullException ("value"); Options = ParserOptions.Default.Clone (); Field = id.ToHeaderName (); Id = id; SetValue (charset, value); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Header"/> class. /// </summary> /// <remarks> /// Creates a new message or entity header for the specified field and /// value pair. The encoding is used to determine which charset to use /// when encoding the value according to the rules of rfc2047. /// </remarks> /// <param name="encoding">The character encoding that should be used to /// encode the header value.</param> /// <param name="id">The header identifier.</param> /// <param name="value">The value of the header.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="value"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="id"/> is not a valid <see cref="HeaderId"/>. /// </exception> public Header (Encoding encoding, HeaderId id, string value) { if (encoding == null) throw new ArgumentNullException ("encoding"); if (id == HeaderId.Unknown) throw new ArgumentOutOfRangeException ("id"); if (value == null) throw new ArgumentNullException ("value"); Options = ParserOptions.Default.Clone (); Field = id.ToHeaderName (); Id = id; rawField = Encoding.ASCII.GetBytes (Field); SetValue (encoding, value); }
/// <summary> /// Sets the text content and the charset parameter in the Content-Type header. /// </summary> /// <remarks> /// This method is similar to setting the <see cref="Text"/> property, but allows /// specifying a charset encoding to use. Also updates the /// <see cref="ContentType.Charset"/> property. /// </remarks> /// <param name="encoding">The charset encoding.</param> /// <param name="text">The text content.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="text"/> is <c>null</c>.</para> /// </exception> public void SetText (Encoding encoding, string text) { if (encoding == null) throw new ArgumentNullException ("encoding"); if (text == null) throw new ArgumentNullException ("text"); ContentType.Parameters["charset"] = CharsetUtils.GetMimeCharset (encoding); var content = new MemoryStream (encoding.GetBytes (text)); ContentObject = new ContentObject (content); }
/// <summary> /// Asynchronously authenticates using the specified user name and password. /// </summary> /// <remarks> /// <para>If the server supports one or more SASL authentication mechanisms, /// then the SASL mechanisms that both the client and server support are tried /// in order of greatest security to weakest security. Once a SASL /// authentication mechanism is found that both client and server support, /// the credentials are used to authenticate.</para> /// <para>If the server does not support SASL or if no common SASL mechanisms /// can be found, then the default login command is used as a fallback.</para> /// <note type="tip">To prevent the usage of certain authentication mechanisms, /// simply remove them from the <see cref="AuthenticationMechanisms"/> hash set /// before calling this method.</note> /// </remarks> /// <returns>An asynchronous task context.</returns> /// <param name="encoding">The encoding to use for the user's credentials.</param> /// <param name="userName">The user name.</param> /// <param name="password">The password.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="userName"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="password"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="MailService"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The <see cref="MailService"/> is not connected or is already authenticated. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="MailKit.Security.AuthenticationException"> /// Authentication using the supplied credentials has failed. /// </exception> /// <exception cref="MailKit.Security.SaslException"> /// A SASL authentication error occurred. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// A protocol error occurred. /// </exception> public Task AuthenticateAsync (Encoding encoding, string userName, string password, CancellationToken cancellationToken = default (CancellationToken)) { if (encoding == null) throw new ArgumentNullException ("encoding"); if (userName == null) throw new ArgumentNullException ("userName"); if (password == null) throw new ArgumentNullException ("password"); var credentials = new NetworkCredential (userName, password); return AuthenticateAsync (encoding, credentials, cancellationToken); }
/// <summary> /// Asynchronously authenticates using the supplied credentials. /// </summary> /// <remarks> /// <para>If the server supports one or more SASL authentication mechanisms, /// then the SASL mechanisms that both the client and server support are tried /// in order of greatest security to weakest security. Once a SASL /// authentication mechanism is found that both client and server support, /// the credentials are used to authenticate.</para> /// <para>If the server does not support SASL or if no common SASL mechanisms /// can be found, then the default login command is used as a fallback.</para> /// <note type="tip">To prevent the usage of certain authentication mechanisms, /// simply remove them from the <see cref="AuthenticationMechanisms"/> hash set /// before calling this method.</note> /// </remarks> /// <returns>An asynchronous task context.</returns> /// <param name="encoding">The encoding to use for the user's credentials.</param> /// <param name="credentials">The user's credentials.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="credentials"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="MailService"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The <see cref="MailService"/> is not connected or is already authenticated. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="MailKit.Security.AuthenticationException"> /// Authentication using the supplied credentials has failed. /// </exception> /// <exception cref="MailKit.Security.SaslException"> /// A SASL authentication error occurred. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// A protocol error occurred. /// </exception> public virtual Task AuthenticateAsync (Encoding encoding, ICredentials credentials, CancellationToken cancellationToken = default (CancellationToken)) { if (encoding == null) throw new ArgumentNullException ("encoding"); if (credentials == null) throw new ArgumentNullException ("credentials"); return Task.Factory.StartNew (() => { lock (SyncRoot) { Authenticate (encoding, credentials, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Authenticates using the supplied credentials. /// </summary> /// <remarks> /// <para>If the server supports one or more SASL authentication mechanisms, /// then the SASL mechanisms that both the client and server support are tried /// in order of greatest security to weakest security. Once a SASL /// authentication mechanism is found that both client and server support, /// the credentials are used to authenticate.</para> /// <para>If the server does not support SASL or if no common SASL mechanisms /// can be found, then the default login command is used as a fallback.</para> /// <note type="tip">To prevent the usage of certain authentication mechanisms, /// simply remove them from the <see cref="AuthenticationMechanisms"/> hash set /// before calling this method.</note> /// </remarks> /// <param name="encoding">The encoding to use for the user's credentials.</param> /// <param name="credentials">The user's credentials.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="encoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="credentials"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="MailService"/> has been disposed. /// </exception> /// <exception cref="System.InvalidOperationException"> /// The <see cref="MailService"/> is not connected or is already authenticated. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="MailKit.Security.AuthenticationException"> /// Authentication using the supplied credentials has failed. /// </exception> /// <exception cref="MailKit.Security.SaslException"> /// A SASL authentication error occurred. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// A protocol error occurred. /// </exception> public abstract void Authenticate (Encoding encoding, ICredentials credentials, CancellationToken cancellationToken = default (CancellationToken));
/// <summary> /// Encodes the phrase. /// </summary> /// <remarks> /// Encodes the phrase according to the rules of rfc2047 using /// the specified charset encoding and formatting options. /// </remarks> /// <returns>The encoded phrase.</returns> /// <param name="options">The formatting options</param> /// <param name="charset">The charset encoding.</param> /// <param name="phrase">The phrase to encode.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="charset"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="phrase"/> is <c>null</c>.</para> /// </exception> public static byte[] EncodePhrase (FormatOptions options, Encoding charset, string phrase) { if (options == null) throw new ArgumentNullException ("options"); if (charset == null) throw new ArgumentNullException ("charset"); if (phrase == null) throw new ArgumentNullException ("phrase"); return Encode (options, charset, phrase, true); }
static void AppendEncodedWord (StringBuilder str, Encoding charset, string text, int startIndex, int length, QEncodeMode mode) { var chars = new char[length]; IMimeEncoder encoder; byte[] word, encoded; char encoding; int len; text.CopyTo (startIndex, chars, 0, length); try { word = CharsetConvert (charset, chars, length, out len); } catch { charset = Encoding.UTF8; word = CharsetConvert (charset, chars, length, out len); } if (CharsetRequiresBase64 (charset) || GetBestContentEncoding (word, 0, len) == ContentEncoding.Base64) { encoder = new Base64Encoder (true); encoding = 'b'; } else { encoder = new QEncoder (mode); encoding = 'q'; } encoded = new byte[encoder.EstimateOutputLength (len)]; len = encoder.Flush (word, 0, len, encoded); str.AppendFormat ("=?{0}?{1}?", CharsetUtils.GetMimeCharset (charset), encoding); for (int i = 0; i < len; i++) str.Append ((char) encoded[i]); str.Append ("?="); }
static byte[] EncodeUnstructuredHeader (ParserOptions options, FormatOptions format, Encoding charset, string field, string value) { if (format.International) { var folded = Fold (format, field, value); return Encoding.UTF8.GetBytes (folded); } var encoded = Rfc2047.EncodeText (format, charset, value); return Rfc2047.FoldUnstructuredHeader (format, field, encoded); }
static byte[] CharsetConvert (Encoding charset, char[] word, int length, out int converted) { var encoder = charset.GetEncoder (); int count = encoder.GetByteCount (word, 0, length, true); var encoded = new byte[count]; converted = encoder.GetBytes (word, 0, length, encoded, 0, true); return encoded; }
static bool CharsetRequiresBase64 (Encoding encoding) { // https://tools.ietf.org/rfc/rfc1468.txt // // ISO-2022-JP may also be used in MIME Part 2 headers. The "B" // encoding should be used with ISO-2022-JP text. return encoding.CodePage == 50220 || encoding.CodePage == 50222; }
/// <summary> /// Encodes the unstructured text. /// </summary> /// <remarks> /// Encodes the unstructured text according to the rules of rfc2047 /// using the specified charset encoding. /// </remarks> /// <returns>The encoded text.</returns> /// <param name="charset">The charset encoding.</param> /// <param name="text">The text to encode.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="charset"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="text"/> is <c>null</c>.</para> /// </exception> public static byte[] EncodeText (Encoding charset, string text) { return EncodeText (FormatOptions.Default, charset, text); }
/// <summary> /// Encodes the unstructured text. /// </summary> /// <remarks> /// Encodes the unstructured text according to the rules of rfc2047 /// using the specified charset encoding and formatting options. /// </remarks> /// <returns>The encoded text.</returns> /// <param name="options">The formatting options</param> /// <param name="charset">The charset encoding.</param> /// <param name="text">The text to encode.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="charset"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="text"/> is <c>null</c>.</para> /// </exception> public static byte[] EncodeText (FormatOptions options, Encoding charset, string text) { if (options == null) throw new ArgumentNullException ("options"); if (charset == null) throw new ArgumentNullException ("charset"); if (text == null) throw new ArgumentNullException ("text"); return Encode (options, charset, text, false); }
/// <summary> /// Encodes the phrase. /// </summary> /// <remarks> /// Encodes the phrase according to the rules of rfc2047 using /// the specified charset encoding. /// </remarks> /// <returns>The encoded phrase.</returns> /// <param name="charset">The charset encoding.</param> /// <param name="phrase">The phrase to encode.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="charset"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="phrase"/> is <c>null</c>.</para> /// </exception> public static byte[] EncodePhrase (Encoding charset, string phrase) { return EncodePhrase (FormatOptions.Default, charset, phrase); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.IO.Filters.CharsetFilter"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="CharsetFilter"/> to convert text from the specified /// source encoding into the target charset encoding. /// </remarks> /// <param name="sourceEncoding">Source encoding.</param> /// <param name="targetEncoding">Target encoding.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="sourceEncoding"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="targetEncoding"/> is <c>null</c>.</para> /// </exception> public CharsetFilter (Encoding sourceEncoding, Encoding targetEncoding) { if (sourceEncoding == null) throw new ArgumentNullException ("sourceEncoding"); if (targetEncoding == null) throw new ArgumentNullException ("targetEncoding"); SourceEncoding = sourceEncoding; TargetEncoding = targetEncoding; decoder = (Decoder) SourceEncoding.GetDecoder (); encoder = (Encoder) TargetEncoding.GetEncoder (); }
static IList<Word> GetRfc822Words (FormatOptions options, Encoding charset, string text, bool phrase) { var encoder = charset.GetEncoder (); var words = new List<Word> (); var chars = new char[2]; var saved = new Word (); var word = new Word (); int nchars, n, i = 0; char c; while (i < text.Length) { c = text[i++]; if (c < 256 && IsBlank (c)) { if (word.ByteCount > 0) { words.Add (word); word = new Word (); } word.StartIndex = i; } else { // save state in case adding this character exceeds the max line length word.CopyTo (saved); if (c < 127) { if (IsCtrl (c)) { word.Encoding = options.AllowMixedHeaderCharsets ? Math.Max (word.Encoding, 1) : 2; word.Type = WordType.EncodedWord; word.EncodeCount++; } else if (phrase && !IsAtom (c)) { // phrases can have quoted strings if (word.Type == WordType.Atom) word.Type = WordType.QuotedString; } if (c == '"' || c == '\\') word.QuotedPairs++; word.ByteCount++; word.CharCount++; nchars = 1; } else if (c < 256) { // iso-8859-1 word.Encoding = options.AllowMixedHeaderCharsets ? Math.Max (word.Encoding, 1) : 2; word.Type = WordType.EncodedWord; word.EncodeCount++; word.ByteCount++; word.CharCount++; nchars = 1; } else { if (char.IsSurrogatePair (text, i - 1)) { chars[1] = text[i++]; nchars = 2; } else { nchars = 1; } chars[0] = c; try { n = encoder.GetByteCount (chars, 0, nchars, true); } catch { n = 3; } word.Type = WordType.EncodedWord; word.CharCount += nchars; word.EncodeCount += n; word.ByteCount += n; word.Encoding = 2; } if (ExceedsMaxLineLength (options, charset, word)) { // restore our previous state saved.CopyTo (word); i -= nchars; // Note: if the word is longer than what we can fit on // one line, then we need to encode it. if (word.Type == WordType.Atom) { word.Type = WordType.EncodedWord; // in order to fit this long atom under MaxLineLength, we need to // account for the added length of =?us-ascii?q?...?= n = "us-ascii".Length + 7; word.CharCount -= n; word.ByteCount -= n; i -= n; } words.Add (word); saved.Type = word.Type; word = new Word (); // Note: the word-type needs to be preserved when breaking long words. word.Type = saved.Type; word.StartIndex = i; } } } if (word.ByteCount > 0) words.Add (word); return words; }
byte[] FormatRawValue (FormatOptions format, Encoding encoding) { switch (Id) { case HeaderId.DispositionNotificationTo: case HeaderId.ResentFrom: case HeaderId.ResentBcc: case HeaderId.ResentCc: case HeaderId.ResentTo: case HeaderId.From: case HeaderId.Bcc: case HeaderId.Cc: case HeaderId.To: return EncodeAddressHeader (Options, format, encoding, Field, textValue); case HeaderId.Received: return EncodeReceivedHeader (Options, format, encoding, Field, textValue); case HeaderId.ResentMessageId: case HeaderId.MessageId: case HeaderId.ContentId: return EncodeMessageIdHeader (Options, format, encoding, Field, textValue); case HeaderId.References: return EncodeReferencesHeader (Options, format, encoding, Field, textValue); case HeaderId.ContentDisposition: return EncodeContentDisposition (Options, format, encoding, Field, textValue); case HeaderId.ContentType: return EncodeContentType (Options, format, encoding, Field, textValue); case HeaderId.DkimSignature: return EncodeDkimSignatureHeader (Options, format, encoding, Field, textValue); default: return EncodeUnstructuredHeader (Options, format, encoding, Field, textValue); } }
static bool ExceedsMaxLineLength (FormatOptions options, Encoding charset, Word word) { int length; switch (word.Type) { case WordType.EncodedWord: switch (word.Encoding) { case 1: length = EstimateEncodedWordLength ("iso-8859-1", word.ByteCount, word.EncodeCount); break; case 0: length = EstimateEncodedWordLength ("us-ascii", word.ByteCount, word.EncodeCount); break; default: length = EstimateEncodedWordLength (charset, word.ByteCount, word.EncodeCount); break; } break; case WordType.QuotedString: length = word.ByteCount + word.QuotedPairs + 2; break; default: length = word.ByteCount; break; } return length + 1 >= options.MaxLineLength; }
static byte[] EncodeContentType (ParserOptions options, FormatOptions format, Encoding charset, string field, string value) { var contentType = ContentType.Parse (options, value); var encoded = contentType.Encode (format, charset); return Encoding.UTF8.GetBytes (encoded); }
static int EstimateEncodedWordLength (Encoding charset, int byteCount, int encodeCount) { return EstimateEncodedWordLength (CharsetUtils.GetMimeCharset (charset), byteCount, encodeCount); }
static bool ShouldMergeWords (FormatOptions options, Encoding charset, IList<Word> words, Word word, int i) { Word next = words[i]; int lwspCount = next.StartIndex - (word.StartIndex + word.CharCount); int length = word.ByteCount + lwspCount + next.ByteCount; int encoded = word.EncodeCount + next.EncodeCount; int quoted = word.QuotedPairs + next.QuotedPairs; switch (word.Type) { case WordType.Atom: if (next.Type == WordType.EncodedWord) return false; return length + 1 < options.MaxLineLength; case WordType.QuotedString: if (next.Type == WordType.EncodedWord) return false; return length + quoted + 3 < options.MaxLineLength; case WordType.EncodedWord: if (next.Type == WordType.Atom) { // whether we merge or not is dependent upon: // 1. the number of atoms in a row after 'word' // 2. if there is another encoded-word after // the string of atoms. bool merge = false; int natoms = 0; for (int j = i + 1; j < words.Count && natoms < 3; j++) { if (words[j].Type != WordType.Atom) { merge = true; break; } natoms++; } // if all the words after the encoded-word are atoms, don't merge if (!merge) return false; } // avoid merging with qstrings if (next.Type == WordType.QuotedString) return false; switch (Math.Max (word.Encoding, next.Encoding)) { case 1: length = EstimateEncodedWordLength ("iso-8859-1", length, encoded); break; case 0: length = EstimateEncodedWordLength ("us-ascii", length, encoded); break; default: length = EstimateEncodedWordLength (charset, length, encoded); break; } return length + 1 < options.MaxLineLength; default: return false; } }
static byte[] Encode (FormatOptions options, Encoding charset, string text, bool phrase) { var mode = phrase ? QEncodeMode.Phrase : QEncodeMode.Text; var words = Merge (options, charset, GetRfc822Words (options, charset, text, phrase)); var str = new StringBuilder (); int start, length; Word prev = null; byte[] encoded; foreach (var word in words) { // append the correct number of spaces between words... if (prev != null && !(prev.Type == WordType.EncodedWord && word.Type == WordType.EncodedWord)) { start = prev.StartIndex + prev.CharCount; length = word.StartIndex - start; str.Append (text, start, length); } switch (word.Type) { case WordType.Atom: str.Append (text, word.StartIndex, word.CharCount); break; case WordType.QuotedString: AppendQuoted (str, text, word.StartIndex, word.CharCount); break; case WordType.EncodedWord: if (prev != null && prev.Type == WordType.EncodedWord) { // include the whitespace between these 2 words in the // resulting rfc2047 encoded-word. start = prev.StartIndex + prev.CharCount; length = (word.StartIndex + word.CharCount) - start; str.Append (phrase ? '\t' : ' '); } else { start = word.StartIndex; length = word.CharCount; } switch (word.Encoding) { case 0: // us-ascii AppendEncodedWord (str, Encoding.ASCII, text, start, length, mode); break; case 1: // iso-8859-1 AppendEncodedWord (str, CharsetUtils.Latin1, text, start, length, mode); break; default: // custom charset AppendEncodedWord (str, charset, text, start, length, mode); break; } break; } prev = word; } encoded = new byte[str.Length]; for (int i = 0; i < str.Length; i++) encoded[i] = (byte) str[i]; return encoded; }
/// <summary> /// Gets the decoded text content using the provided charset encoding to /// override the charset specified in the Content-Type parameters. /// </summary> /// <remarks> /// Uses the provided charset encoding to convert the raw text content /// into a unicode string, overriding any charset specified in the /// Content-Type header. /// </remarks> /// <returns>The decoded text.</returns> /// <param name="encoding">The charset encoding to use.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="encoding"/> is <c>null</c>. /// </exception> public string GetText (Encoding encoding) { if (encoding == null) throw new ArgumentNullException ("encoding"); if (ContentObject == null) return string.Empty; using (var memory = new MemoryStream ()) { ContentObject.DecodeTo (memory); #if PORTABLE var buffer = memory.ToArray (); #else var buffer = memory.GetBuffer (); #endif return encoding.GetString (buffer, 0, (int) memory.Length); } }
static IList<Word> Merge (FormatOptions options, Encoding charset, IList<Word> words) { if (words.Count < 2) return words; int lwspCount, encoding, encoded, quoted, byteCount, length; var merged = new List<Word> (); Word word, next; word = words[0]; merged.Add (word); // first pass: merge qstrings with adjacent qstrings and encoded-words with adjacent encoded-words for (int i = 1; i < words.Count; i++) { next = words[i]; if (word.Type != WordType.Atom && word.Type == next.Type) { lwspCount = next.StartIndex - (word.StartIndex + word.CharCount); byteCount = word.ByteCount + lwspCount + next.ByteCount; encoding = Math.Max (word.Encoding, next.Encoding); encoded = word.EncodeCount + next.EncodeCount; quoted = word.QuotedPairs + next.QuotedPairs; if (word.Type == WordType.EncodedWord) { switch (encoding) { case 1: length = EstimateEncodedWordLength ("iso-8859-1", byteCount, encoded); break; case 0: length = EstimateEncodedWordLength ("us-ascii", byteCount, encoded); break; default: length = EstimateEncodedWordLength (charset, byteCount, encoded); break; } } else { length = byteCount + quoted + 2; } if (length + 1 < options.MaxLineLength) { word.CharCount = (next.StartIndex + next.CharCount) - word.StartIndex; word.ByteCount = byteCount; word.EncodeCount = encoded; word.QuotedPairs = quoted; word.Encoding = encoding; continue; } } merged.Add (next); word = next; } words = merged; merged = new List<Word> (); word = words[0]; merged.Add (word); // second pass: now merge atoms with the other words for (int i = 1; i < words.Count; i++) { next = words[i]; if (ShouldMergeWords (options, charset, words, word, i)) { // the resulting word is the max of the 2 types lwspCount = next.StartIndex - (word.StartIndex + word.CharCount); word.Type = (WordType) Math.Max ((int) word.Type, (int) next.Type); word.CharCount = (next.StartIndex + next.CharCount) - word.StartIndex; word.ByteCount = word.ByteCount + lwspCount + next.ByteCount; word.Encoding = Math.Max (word.Encoding, next.Encoding); word.EncodeCount = word.EncodeCount + next.EncodeCount; word.QuotedPairs = word.QuotedPairs + next.QuotedPairs; } else { merged.Add (next); word = next; } } return merged; }