internal MimeEntityConstructorArgs (ParserOptions options, ContentType ctype, IEnumerable<Header> headers, bool toplevel) { ParserOptions = options; IsTopLevel = toplevel; ContentType = ctype; Headers = headers; }
private static MimePart GetMimePart(AttachmentBase item) { var mimeType = item.ContentType.ToString(); var contentType = ContentType.Parse(mimeType); var attachment = item as Attachment; MimePart part; if (contentType.MediaType.Equals("text", StringComparison.OrdinalIgnoreCase)) { // Original: part = new TextPart(contentType); // Due to constructor of TextPart(ContentType contentType) being internal, // mimic the instantiation by using MimePart(ContentType contentType) part = new MimePart(contentType); } else { part = new MimePart(contentType); } if (attachment != null) { var disposition = attachment.ContentDisposition.ToString(); part.ContentDisposition = ContentDisposition.Parse(disposition); } switch (item.TransferEncoding) { case TransferEncoding.QuotedPrintable: part.ContentTransferEncoding = ContentEncoding.QuotedPrintable; break; case TransferEncoding.Base64: part.ContentTransferEncoding = ContentEncoding.Base64; break; case TransferEncoding.SevenBit: part.ContentTransferEncoding = ContentEncoding.SevenBit; break; case TransferEncoding.EightBit: part.ContentTransferEncoding = ContentEncoding.EightBit; break; } if (item.ContentId != null) { part.ContentId = item.ContentId; } var stream = new MemoryBlockStream(); item.ContentStream.CopyTo(stream); stream.Position = 0; part.ContentObject = new ContentObject(stream); return(part); }
private static MimePart GetMimePart(AttachmentBase item) { var mimeType = item.ContentType.ToString(); var contentType = ContentType.Parse(mimeType); var attachment = item as Attachment; var part = new MimePart(contentType); // if (attachment != null) { var disposition = attachment.ContentDisposition.ToString(); part.ContentDisposition = ContentDisposition.Parse(disposition); } // Adjust the transfer encoding switch (item.TransferEncoding) { case TransferEncoding.QuotedPrintable: part.ContentTransferEncoding = ContentEncoding.QuotedPrintable; break; case TransferEncoding.Base64: part.ContentTransferEncoding = ContentEncoding.Base64; break; case TransferEncoding.SevenBit: part.ContentTransferEncoding = ContentEncoding.SevenBit; break; case TransferEncoding.EightBit: part.ContentTransferEncoding = ContentEncoding.EightBit; break; case TransferEncoding.Unknown: break; default: throw new ArgumentOutOfRangeException(); } // Adjust the attachment content identifier if (item.ContentId != null) { part.ContentId = item.ContentId; } // Copy the content of the attachment var stream = new MemoryBlockStream(); item.ContentStream.CopyTo(stream); stream.Position = 0; part.Content = new MimeContent(stream); // Done return(part); }
public void TestBreakingOfLongParamValues() { string encoded, expected; ContentType type; expected = "Content-Type: text/plain; charset=iso-8859-1;\n\tname*0=\"this is a really really long filename that should force MimeKi\";\n\tname*1=\"t to break it apart - yay!.html\""; type = new ContentType ("text", "plain"); type.Parameters.Add ("charset", "iso-8859-1"); type.Parameters.Add ("name", "this is a really really long filename that should force MimeKit to break it apart - yay!.html"); encoded = type.ToString (Encoding.UTF8, true); Assert.AreEqual (expected, encoded, "Encoded Content-Type does not match: {0}", expected); }
private MimePart CreateMimePart(string mediaType, string mediaSubtype, string filename) { var contentType = new MimeKit.ContentType(mediaType, mediaSubtype); IContentObject contentObject = A.Fake <IContentObject>(); A.CallTo(() => contentObject.Stream).Returns(new MemoryStream()); return(new MimePart(contentType) { FileName = filename, ContentObject = contentObject }); }
//This handles case where ContentType is used instead of Content-Type //this is seen in aggregate reports generated by Trustwave SEG software. public string GetContentType(MimePart mimePart) { string contentType = mimePart.ContentType.MimeType.ToLower(); if (contentType == ContentType.TextPlain) { Dictionary <string, Header> headers = mimePart.Headers.ToDictionary(_ => _.Field); if (headers.TryGetValue(AlternativeContentTypeHeader, out Header header)) { MimeKit.ContentType updatedContentType = MimeKit.ContentType.Parse(ParserOptions.Default, header.RawValue); string updatedContentTypeString = updatedContentType.MimeType.ToLower(); _log.LogInformation($"Updated content type from {contentType} to {updatedContentTypeString}"); return(updatedContentTypeString); } } return(contentType); }
private MimePart CreateMimePart(string mediaType, string mediaSubtype, string filename, params Header[] headers) { var contentType = new MimeKit.ContentType(mediaType, mediaSubtype); IMimeContent contentObject = A.Fake <IMimeContent>(); A.CallTo(() => contentObject.Stream).Returns(new MemoryStream()); MimePart mimePart = new MimePart(contentType) { FileName = filename, Content = contentObject }; foreach (Header header in headers) { mimePart.Headers.Add(header); } return(mimePart); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MimePart"/> class /// with the specified content type. /// </summary> /// <remarks> /// Creates a new <see cref="MimePart"/> with the specified Content-Type value. /// </remarks> /// <param name="contentType">The content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="contentType"/> is <c>null</c>. /// </exception> /// <exception cref="MimeKit.ParseException"> /// <paramref name="contentType"/> could not be parsed. /// </exception> public MimePart(string contentType) : base(ContentType.Parse(contentType)) { }
/// <summary> /// Load a <see cref="MimeEntity"/> from the specified content stream. /// </summary> /// <remarks> /// This method is mostly meant for use with APIs such as <see cref="System.Net.HttpWebResponse"/> /// where the headers are parsed separately from the content. /// </remarks> /// <returns>The parsed MIME entity.</returns> /// <param name="options">The parser options.</param> /// <param name="contentType">The Content-Type of the stream.</param> /// <param name="content">The content stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="contentType"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="content"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.FormatException"> /// There was an error parsing the entity. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public static MimeEntity Load (ParserOptions options, ContentType contentType, Stream content, CancellationToken cancellationToken = default (CancellationToken)) { if (options == null) throw new ArgumentNullException ("options"); if (contentType == null) throw new ArgumentNullException ("contentType"); if (content == null) throw new ArgumentNullException ("content"); var format = FormatOptions.Default.Clone (); format.NewLineFormat = NewLineFormat.Dos; var encoded = contentType.Encode (format, Encoding.UTF8); var header = string.Format ("Content-Type:{0}\r\n", encoded); var chained = new ChainedStream (); chained.Add (new MemoryStream (Encoding.UTF8.GetBytes (header), false)); chained.Add (content); return Load (options, chained, cancellationToken); }
static ContentType CreateContentType (string type, string subtype, string partSpecifier) { var contentType = new ContentType (type, subtype); contentType.Parameters.Add ("part-specifier", partSpecifier); return contentType; }
internal static MimeEntity Create(ParserOptions options, ContentType ctype, IEnumerable<Header> headers, bool toplevel) { var entity = new MimeEntityConstructorInfo (options, ctype, headers, toplevel); var subtype = ctype.MediaSubtype.ToLowerInvariant (); var type = ctype.MediaType.ToLowerInvariant (); if (CustomMimeTypes.Count > 0) { var mimeType = string.Format ("{0}/{1}", type, subtype); lock (CustomMimeTypes) { ConstructorInfo ctor; if (CustomMimeTypes.TryGetValue (mimeType, out ctor)) return (MimeEntity) ctor.Invoke (new object[] { entity }); } } if (type == "message") { if (subtype == "partial") return new MessagePartial (entity); return new MessagePart (entity); } if (type == "multipart") { if (subtype == "encrypted") return new MultipartEncrypted (entity); if (subtype == "signed") return new MultipartSigned (entity); return new Multipart (entity); } if (type == "application") { switch (subtype) { case "x-pkcs7-signature": case "pkcs7-signature": return new ApplicationPkcs7Signature (entity); case "x-pgp-encrypted": case "pgp-encrypted": return new ApplicationPgpEncrypted (entity); case "x-pgp-signature": case "pgp-signature": return new ApplicationPgpSignature (entity); case "x-pkcs7-mime": case "pkcs7-mime": return new ApplicationPkcs7Mime (entity); } } if (type == "text") return new TextPart (entity); return new MimePart (entity); }
static ContentType ParseContentType(ImapEngine engine, CancellationToken cancellationToken) { var type = ReadStringToken (engine, cancellationToken); var subtype = ReadStringToken (engine, cancellationToken); var token = engine.ReadToken (cancellationToken); ContentType contentType; if (token.Type == ImapTokenType.Nil) return new ContentType (type, subtype); if (token.Type != ImapTokenType.OpenParen) throw ImapEngine.UnexpectedToken (token, false); var builder = new StringBuilder (); builder.AppendFormat ("{0}/{1}", type, subtype); ParseParameterList (builder, engine, cancellationToken); if (!ContentType.TryParse (builder.ToString (), out contentType)) contentType = new ContentType (type, subtype); return contentType; }
/// <summary> /// Tries to parse the given text into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="text">The text to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="text"/> is <c>null</c>. /// </exception> public static bool TryParse(string text, out ContentType type) { if (text == null) throw new ArgumentNullException ("text"); var buffer = Encoding.UTF8.GetBytes (text); int index = 0; return TryParse (ParserOptions.Default, buffer, ref index, buffer.Length, false, out type); }
/// <summary> /// Asynchronously write the <see cref="MimePart"/> to the specified output stream. /// </summary> /// <remarks> /// Asynchronously writes the MIME part to the output stream. /// </remarks> /// <returns>An awaitable task.</returns> /// <param name="options">The formatting options.</param> /// <param name="stream">The output stream.</param> /// <param name="contentOnly"><c>true</c> if only the content should be written; otherwise, <c>false</c>.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public override async Task WriteToAsync(FormatOptions options, Stream stream, bool contentOnly, CancellationToken cancellationToken = default(CancellationToken)) { await base.WriteToAsync(options, stream, contentOnly, cancellationToken).ConfigureAwait(false); if (Content == null) { return; } var isText = ContentType.IsMimeType("text", "*") || ContentType.IsMimeType("message", "*"); if (Content.Encoding != encoding) { if (encoding == ContentEncoding.UUEncode) { var begin = string.Format("begin 0644 {0}", FileName ?? "unknown"); var buffer = Encoding.UTF8.GetBytes(begin); await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false); } // transcode the content into the desired Content-Transfer-Encoding using (var filtered = new FilteredStream(stream)) { filtered.Add(EncoderFilter.Create(encoding)); if (encoding != ContentEncoding.Binary) { filtered.Add(options.CreateNewLineFilter(EnsureNewLine)); } await Content.DecodeToAsync(filtered, cancellationToken).ConfigureAwait(false); await filtered.FlushAsync(cancellationToken).ConfigureAwait(false); } if (encoding == ContentEncoding.UUEncode) { var buffer = Encoding.ASCII.GetBytes("end"); await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false); } } else if (encoding == ContentEncoding.Binary) { // Do not alter binary content. await Content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); } else if (options.VerifyingSignature && Content.NewLineFormat.HasValue && Content.NewLineFormat.Value == NewLineFormat.Mixed) { // Allow pass-through of the original parsed content without canonicalization when verifying signatures // if the content contains a mix of line-endings. // // See https://github.com/jstedfast/MimeKit/issues/569 for details. await Content.WriteToAsync(stream, cancellationToken).ConfigureAwait(false); } else { using (var filtered = new FilteredStream(stream)) { // Note: if we are writing the top-level MimePart, make sure it ends with a new-line so that // MimeMessage.WriteTo() *always* ends with a new-line. filtered.Add(options.CreateNewLineFilter(EnsureNewLine)); await Content.WriteToAsync(filtered, cancellationToken).ConfigureAwait(false); await filtered.FlushAsync(cancellationToken).ConfigureAwait(false); } } }
/// <summary> /// Tries to parse the given text into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the specified text. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="text">The text to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="text"/> is <c>null</c>. /// </exception> public static bool TryParse(string text, out ContentType type) { return(TryParse(ParserOptions.Default, text, out type)); }
internal TextPart (ContentType contentType) : base (contentType) { }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the supplied buffer starting at the specified index. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="options">The parser options.</param> /// <param name="buffer">The input buffer.</param> /// <param name="startIndex">The starting index of the input buffer.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="buffer"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> is out of range. /// </exception> public static bool TryParse(ParserOptions options, byte[] buffer, int startIndex, out ContentType type) { ParseUtils.ValidateArguments(options, buffer, startIndex); int index = startIndex; return(TryParse(options, buffer, ref index, buffer.Length, false, out type)); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the specified buffer. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="buffer">The input buffer.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="buffer"/> is <c>null</c>. /// </exception> public static bool TryParse(byte[] buffer, out ContentType type) { return(TryParse(ParserOptions.Default, buffer, out type)); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the supplied buffer starting at the given index /// and spanning across the specified number of bytes. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="buffer">The input buffer.</param> /// <param name="startIndex">The starting index of the input buffer.</param> /// <param name="length">The number of bytes in the input buffer to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="buffer"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify /// a valid range in the byte array. /// </exception> public static bool TryParse(byte[] buffer, int startIndex, int length, out ContentType type) { return(TryParse(ParserOptions.Default, buffer, startIndex, length, out type)); }
internal static bool TryParse(ParserOptions options, byte[] text, ref int index, int endIndex, bool throwOnError, out ContentType contentType) { string type, subtype; int start; contentType = null; if (!ParseUtils.SkipCommentsAndWhiteSpace(text, ref index, endIndex, throwOnError)) { return(false); } start = index; if (!SkipType(text, ref index, endIndex)) { if (throwOnError) { throw new ParseException(string.Format("Invalid type token at position {0}", start), start, index); } return(false); } type = Encoding.ASCII.GetString(text, start, index - start); if (!ParseUtils.SkipCommentsAndWhiteSpace(text, ref index, endIndex, throwOnError)) { return(false); } if (index >= endIndex || text[index] != (byte)'/') { if (throwOnError) { throw new ParseException(string.Format("Expected '/' at position {0}", index), index, index); } return(false); } // skip over the '/' index++; if (!ParseUtils.SkipCommentsAndWhiteSpace(text, ref index, endIndex, throwOnError)) { return(false); } start = index; if (!ParseUtils.SkipToken(text, ref index, endIndex)) { if (throwOnError) { throw new ParseException(string.Format("Invalid atom token at position {0}", start), start, index); } return(false); } subtype = Encoding.ASCII.GetString(text, start, index - start); if (!ParseUtils.SkipCommentsAndWhiteSpace(text, ref index, endIndex, throwOnError)) { return(false); } contentType = new ContentType(type, subtype); if (index >= endIndex) { return(true); } if (text[index] != (byte)';') { if (throwOnError) { throw new ParseException(string.Format("Expected ';' at position {0}", index), index, index); } return(false); } index++; if (!ParseUtils.SkipCommentsAndWhiteSpace(text, ref index, endIndex, throwOnError)) { return(false); } if (index >= endIndex) { return(true); } ParameterList parameters; if (!ParameterList.TryParse(options, text, ref index, endIndex, throwOnError, out parameters)) { return(false); } contentType.Parameters = parameters; return(true); }
/// <summary> /// Load a <see cref="MimeEntity"/> from the specified content stream. /// </summary> /// <remarks> /// This method is mostly meant for use with APIs such as <see cref="System.Net.HttpWebResponse"/> /// where the headers are parsed separately from the content. /// </remarks> /// <returns>The parsed MIME entity.</returns> /// <param name="contentType">The Content-Type of the stream.</param> /// <param name="content">The content stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="contentType"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="content"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.FormatException"> /// There was an error parsing the entity. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public static MimeEntity Load(ContentType contentType, Stream content, CancellationToken cancellationToken = default(CancellationToken)) { return(Load(ParserOptions.Default, contentType, content, cancellationToken)); }
public void TestEncodingOfParamValues() { string encoded, expected; ContentType type; expected = "Content-Type: text/plain; charset=iso-8859-1;\n\tname*=iso-8859-1''Kristoffer%20Br%E5nemyr"; type = new ContentType ("text", "plain"); type.Parameters.Add ("charset", "iso-8859-1"); type.Parameters.Add ("name", "Kristoffer Brånemyr"); encoded = type.ToString (Encoding.UTF8, true); Assert.AreEqual (expected, encoded, "Encoded Content-Type does not match: {0}", expected); }
static System.Net.Mime.ContentType GetContentType(ContentType contentType) { var ctype = new System.Net.Mime.ContentType (); ctype.MediaType = string.Format ("{0}/{1}", contentType.MediaType, contentType.MediaSubtype); foreach (var param in contentType.Parameters) ctype.Parameters.Add (param.Name, param.Value); return ctype; }
/// <summary> /// Writes the <see cref="MimeKit.Multipart"/> to the specified output stream. /// </summary> /// <remarks> /// Writes the multipart MIME entity and its subparts to the output stream. /// </remarks> /// <param name="options">The formatting options.</param> /// <param name="stream">The output stream.</param> /// <param name="contentOnly"><c>true</c> if only the content should be written; otherwise, <c>false</c>.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public override void WriteTo(FormatOptions options, Stream stream, bool contentOnly, CancellationToken cancellationToken = default(CancellationToken)) { base.WriteTo(options, stream, contentOnly, cancellationToken); if (ContentType.IsMimeType("multipart", "signed")) { // don't reformat the headers or content of any children of a multipart/signed if (options.International || options.HiddenHeaders.Count > 0) { options = options.Clone(); options.HiddenHeaders.Clear(); options.International = false; } } var cancellable = stream as ICancellableStream; if (RawPreamble != null && RawPreamble.Length > 0) { WriteBytes(options, stream, RawPreamble, children.Count > 0 || EnsureNewLine, cancellationToken); } var boundary = Encoding.ASCII.GetBytes("--" + Boundary + "--"); if (cancellable != null) { for (int i = 0; i < children.Count; i++) { var msg = children[i] as MessagePart; var multi = children[i] as Multipart; var part = children[i] as MimePart; cancellable.Write(boundary, 0, boundary.Length - 2, cancellationToken); cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); children[i].WriteTo(options, stream, false, cancellationToken); if (msg != null && msg.Message != null && msg.Message.Body != null) { multi = msg.Message.Body as Multipart; part = msg.Message.Body as MimePart; } if ((part != null && part.Content == null) || (multi != null && !multi.WriteEndBoundary)) { continue; } cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); } if (!WriteEndBoundary) { return; } cancellable.Write(boundary, 0, boundary.Length, cancellationToken); if (RawEpilogue == null) { cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); } } else { for (int i = 0; i < children.Count; i++) { var msg = children[i] as MessagePart; var multi = children[i] as Multipart; var part = children[i] as MimePart; cancellationToken.ThrowIfCancellationRequested(); stream.Write(boundary, 0, boundary.Length - 2); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); children[i].WriteTo(options, stream, false, cancellationToken); if (msg != null && msg.Message != null && msg.Message.Body != null) { multi = msg.Message.Body as Multipart; part = msg.Message.Body as MimePart; } if ((part != null && part.Content == null) || (multi != null && !multi.WriteEndBoundary)) { continue; } cancellationToken.ThrowIfCancellationRequested(); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } if (!WriteEndBoundary) { return; } cancellationToken.ThrowIfCancellationRequested(); stream.Write(boundary, 0, boundary.Length); if (RawEpilogue == null) { cancellationToken.ThrowIfCancellationRequested(); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } } if (RawEpilogue != null && RawEpilogue.Length > 0) { WriteBytes(options, stream, RawEpilogue, EnsureNewLine, cancellationToken); } }
public async Task<bool> SendEmailAsync( ISystemEmail from, IEnumerable<ISystemEmail> to, string subject, string body, IEnumerable<ISystemEmail> cced = null, IEnumerable<ISystemEmail> bcced = null, IEnumerable<Attachment> attachments = null) { if (from == null) throw new ArgumentNullException(nameof(from)); if (to == null) throw new ArgumentNullException(nameof(to)); if (string.IsNullOrWhiteSpace(subject)) throw new ArgumentException("Non-empty value expected", nameof(subject)); var message = new MimeMessage { Subject = subject, }; message.From.Add(new MailboxAddress(from.Name, from.Email)); message.To.AddRange(to.Select(x => new MailboxAddress(x.Name, x.Email))); if (cced != null) { message.Cc.AddRange(cced.Select(x => new MailboxAddress(x.Name, x.Email))); } if (bcced != null) { message.Bcc.AddRange(bcced.Select(x => new MailboxAddress(x.Name, x.Email))); } var bodyBuilder = new BodyBuilder { HtmlBody = body, }; if (attachments != null) { foreach (var att in attachments) { if (att.ContentType == null) { bodyBuilder.Attachments.Add(att.FileName, att.Stream); } else { var contentType = new MimeKit.ContentType(att.ContentType.MediaType, att.ContentType.MediaSubtype); foreach (var parameter in att.ContentType.Parameters) { contentType.Parameters.Add(parameter.Key, parameter.Value); } bodyBuilder.Attachments.Add(att.FileName, att.Stream, contentType); } } } message.Body = bodyBuilder.ToMessageBody(); // NOTE: use to debug smtp: new ProtocolLogger("C:\\tmp\\MailKit.log") using (var client = new MailKitClient()) { // TODO: add to config? client.Timeout = 10 * 60 * 1000; client.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; client.AuthenticationMechanisms.Remove("XOAUTH2"); client.Connect(_smtpSettings.Host, _smtpSettings.Port); //client.Connect("smtp.gmail.com", 587, false); //client.Connect("smtp.gmail.com", 465, SecureSocketOptions.SslOnConnect); client.AuthenticationMechanisms.Remove("XOAUTH2"); // due to enabling less secure apps access try { client.Authenticate(_smtpSettings.UserName, _smtpSettings.Password); _logger.Debug("Smtp authentication done"); } catch (Exception e) { _logger.Debug($"Smtp Authenticate failure, to: { string.Join(",", message.To.Mailboxes.Select(x => x.Address).ToArray()) }", e); // TRICK: after this error we are still able to send email //return false; } try { await client.SendAsync(message); _logger.Info($"Email was sent to: { string.Join(",", message.To.Mailboxes.Select(x => x.Address).ToArray()) }"); } catch (Exception e) { _logger.Error($"Email sending failure, to: { string.Join(",", message.To.Mailboxes.Select(x => x.Address).ToArray()) }", e); return false; } client.Disconnect(true); } return true; }
/// <summary> /// Writes the <see cref="MimeKit.Multipart"/> to the specified output stream. /// </summary> /// <remarks> /// Writes the multipart MIME entity and its subparts to the output stream. /// </remarks> /// <param name="options">The formatting options.</param> /// <param name="stream">The output stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public override void WriteTo(FormatOptions options, Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { if (Boundary == null) { Boundary = GenerateBoundary(); } base.WriteTo(options, stream, cancellationToken); if (ContentType.Matches("multipart", "signed")) { // don't reformat the headers or content of any children of a multipart/signed if (options.International || options.HiddenHeaders.Count > 0) { options = options.Clone(); options.HiddenHeaders.Clear(); options.International = false; } } var cancellable = stream as ICancellableStream; if (RawPreamble != null && RawPreamble.Length > 0) { WriteBytes(options, stream, RawPreamble, cancellationToken); } var boundary = Encoding.ASCII.GetBytes("--" + Boundary + "--"); if (cancellable != null) { for (int i = 0; i < children.Count; i++) { cancellable.Write(boundary, 0, boundary.Length - 2, cancellationToken); cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); children[i].WriteTo(options, stream, cancellationToken); cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); } cancellable.Write(boundary, 0, boundary.Length, cancellationToken); cancellable.Write(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken); } else { for (int i = 0; i < children.Count; i++) { cancellationToken.ThrowIfCancellationRequested(); stream.Write(boundary, 0, boundary.Length - 2); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); children[i].WriteTo(options, stream, cancellationToken); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } cancellationToken.ThrowIfCancellationRequested(); stream.Write(boundary, 0, boundary.Length); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } if (RawEpilogue != null && RawEpilogue.Length > 0) { WriteBytes(options, stream, RawEpilogue, cancellationToken); } }
/// <summary> /// Asynchronously writes the <see cref="MimeKit.Multipart"/> to the specified output stream. /// </summary> /// <remarks> /// Asynchronously writes the multipart MIME entity and its subparts to the output stream. /// </remarks> /// <returns>An awaitable task.</returns> /// <param name="options">The formatting options.</param> /// <param name="stream">The output stream.</param> /// <param name="contentOnly"><c>true</c> if only the content should be written; otherwise, <c>false</c>.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public override async Task WriteToAsync(FormatOptions options, Stream stream, bool contentOnly, CancellationToken cancellationToken = default(CancellationToken)) { await base.WriteToAsync(options, stream, contentOnly, cancellationToken).ConfigureAwait(false); if (ContentType.IsMimeType("multipart", "signed")) { // don't hide or reformat the headers of any children of a multipart/signed if (options.International || options.HiddenHeaders.Count > 0) { options = options.Clone(); options.HiddenHeaders.Clear(); options.International = false; } } if (RawPreamble != null && RawPreamble.Length > 0) { await WriteBytesAsync(options, stream, RawPreamble, children.Count > 0 || EnsureNewLine, cancellationToken).ConfigureAwait(false); } var boundary = Encoding.ASCII.GetBytes("--" + Boundary + "--"); for (int i = 0; i < children.Count; i++) { var msg = children[i] as MessagePart; var multi = children[i] as Multipart; var part = children[i] as MimePart; await stream.WriteAsync(boundary, 0, boundary.Length - 2, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false); await children[i].WriteToAsync(options, stream, false, cancellationToken).ConfigureAwait(false); if (msg != null && msg.Message != null && msg.Message.Body != null) { multi = msg.Message.Body as Multipart; part = msg.Message.Body as MimePart; } if ((part != null && part.Content == null) || (multi != null && !multi.WriteEndBoundary)) { continue; } await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false); } if (!WriteEndBoundary) { return; } await stream.WriteAsync(boundary, 0, boundary.Length, cancellationToken).ConfigureAwait(false); if (RawEpilogue == null) { await stream.WriteAsync(options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken).ConfigureAwait(false); } if (RawEpilogue != null && RawEpilogue.Length > 0) { await WriteBytesAsync(options, stream, RawEpilogue, EnsureNewLine, cancellationToken).ConfigureAwait(false); } }
public IActionResult EnviarCorreo(int id, string correo) { var book = _context.Books.Include(x => x.Author).Include(x => x.Borrower).FirstOrDefault(x => x.BookId == id); if (book.Borrower == null) { return(NotFound()); } LendReport LP = new LendReport(); var ms = LP.PrepareReport(book); //Este metodo devuelve algo, devuelve un memorystream, un memorystream es algo que en su buufer puede guardar información, documentos, fotos, archivos, cosas así. var doc = ms.GetBuffer(); //Aquí almacenamos el documento, recuerda que ms es un memorystream que devuelve el metodo preparereport. Los memoryStream tienen un metodo get buffer que te permiten obtener lo que ellos tienen, es decir, el documento o lo que sea que guarden, buffer está en bytes, es decir getbuffer devuelve bytes //Preparando el reporte //Retornar no email ///Preparando mensaje /// //Destinatario, quien lo envia y el topic var message = new MimeMessage(); message.From.Add(new MailboxAddress("CComics", "aquí debes de poner tu email")); message.To.Add(new MailboxAddress(correo)); message.Subject = "Factura de compra en CCcomis"; //Buscando el saludo xd var Hora = DateTime.Now.Hour; var Saludos = ""; if (Hora >= 6 && Hora < 12) { Saludos = "Buenos días"; } else { if (Hora >= 12 && Hora < 19) { Saludos = "Buenas tardes"; } else { Saludos = "Buenas Noches"; } } var builder = new BodyBuilder(); // El cuerpo del mensaje builder.TextBody = Saludos + ", estimado usuario. ¿Qué tal te va? \n" + "Esta es la factura por el prestamo que ha recibido del libro \n" + " ¡Gracias por elegirnos!"; // Agregarmos aquí el documento a vendiar MimeKit.ContentType ct = new MimeKit.ContentType("application", "pdf"); builder.Attachments.Add("Factura", ms.GetBuffer(), ct); //Agregarlos al body todo lo que la clase BodyBuilder nos permitió crear message.Body = builder.ToMessageBody(); using (var client = new SmtpClient()) { try { client.Connect("smtp.gmail.com", 587, false); client.Authenticate("Tu correo", "Tu contrase?A"); client.Send(message); client.Disconnect(true); } catch (Exception) { return(RedirectToAction(nameof(List))); // si no encuentra un gmail ni nada, entonces el enviara dnuevo a la lista, pon tu correo y tu contrase?a en los campos que correspondan } } return(RedirectToAction(nameof(List))); }
internal MimeEntity CreateEntity (ContentType contentType, IEnumerable<Header> headers, bool toplevel) { var entity = new MimeEntityConstructorInfo (this, contentType, headers, toplevel); var subtype = contentType.MediaSubtype.ToLowerInvariant (); var type = contentType.MediaType.ToLowerInvariant (); if (mimeTypes.Count > 0) { var mimeType = string.Format ("{0}/{1}", type, subtype); ConstructorInfo ctor; if (mimeTypes.TryGetValue (mimeType, out ctor)) return (MimeEntity) ctor.Invoke (new object[] { entity }); } if (type == "message") { if (subtype == "partial") return new MessagePartial (entity); return new MessagePart (entity); } if (type == "multipart") { #if ENABLE_CRYPTO if (subtype == "encrypted") return new MultipartEncrypted (entity); if (subtype == "signed") return new MultipartSigned (entity); #endif return new Multipart (entity); } #if ENABLE_CRYPTO if (type == "application") { switch (subtype) { case "x-pkcs7-signature": case "pkcs7-signature": return new ApplicationPkcs7Signature (entity); case "x-pgp-encrypted": case "pgp-encrypted": return new ApplicationPgpEncrypted (entity); case "x-pgp-signature": case "pgp-signature": return new ApplicationPgpSignature (entity); case "x-pkcs7-mime": case "pkcs7-mime": return new ApplicationPkcs7Mime (entity); case "vnd.ms-tnef": case "ms-tnef": return new TnefPart (entity); } } #endif if (type == "text") return new TextPart (entity); return new MimePart (entity); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MimeEntity"/> class. /// </summary> /// <param name="mediaType">The media type.</param> /// <param name="mediaSubtype">The media subtype.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="mediaType"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="mediaSubtype"/> is <c>null</c>.</para> /// </exception> protected MimeEntity(string mediaType, string mediaSubtype) { ContentType = new ContentType (mediaType, mediaSubtype); Headers = new HeaderList (); ContentType.Changed += ContentTypeChanged; Headers.Changed += HeadersChanged; SerializeContentType (); }
static bool ParseContentType (ImapEngine engine, CancellationToken cancellationToken, out ContentType contentType, out string value) { var type = ReadNStringToken (engine, false, cancellationToken) ?? string.Empty; var token = engine.PeekToken (cancellationToken); value = null; if (engine.IsGMail && token.Type == ImapTokenType.OpenParen) { // Note: GMail's IMAP server implementation breaks when it encounters // nested multiparts with the same boundary and returns a BODYSTRUCTURE // like the example in https://github.com/jstedfast/MailKit/issues/205 contentType = null; value = type; return false; } var subtype = ReadNStringToken (engine, false, cancellationToken) ?? string.Empty; token = engine.ReadToken (cancellationToken); if (token.Type == ImapTokenType.Nil) { contentType = new ContentType (type, subtype); return true; } if (token.Type != ImapTokenType.OpenParen) throw ImapEngine.UnexpectedToken (token, false); var builder = new StringBuilder (); builder.AppendFormat ("{0}/{1}", type, subtype); ParseParameterList (builder, engine, cancellationToken); if (!ContentType.TryParse (builder.ToString (), out contentType)) contentType = new ContentType (type, subtype); return true; }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MimeEntity"/> class. /// </summary> /// <remarks> /// Initializes the <see cref="ContentType"/> to the one provided. /// </remarks> /// <param name="contentType">The content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="contentType"/> is <c>null</c>. /// </exception> protected MimeEntity (ContentType contentType) { if (contentType == null) throw new ArgumentNullException ("contentType"); Headers = new HeaderList (); ContentType = contentType; ContentType.Changed += ContentTypeChanged; Headers.Changed += HeadersChanged; SerializeContentType (); }
internal MimeEntity CreateEntity (ContentType contentType, IList<Header> headers, bool toplevel) { var args = new MimeEntityConstructorArgs (this, contentType, headers, toplevel); var subtype = contentType.MediaSubtype.ToLowerInvariant (); var type = contentType.MediaType.ToLowerInvariant (); if (mimeTypes.Count > 0) { var mimeType = string.Format ("{0}/{1}", type, subtype); ConstructorInfo ctor; if (mimeTypes.TryGetValue (mimeType, out ctor)) return (MimeEntity) ctor.Invoke (new object[] { args }); } // Note: message/rfc822 and message/partial are not allowed to be encoded according to rfc2046 // (sections 5.2.1 and 5.2.2, respectively). Since some broken clients will encode them anyway, // it is necessary for us to treat those as opaque blobs instead, and thus the parser should // parse them as normal MimeParts instead of MessageParts. // // Technically message/disposition-notification is only allowed to have use the 7bit encoding // as well, but since MessageDispositionNotification is a MImePart subclass rather than a // MessagePart subclass, it means that the content won't be parsed until later and so we can // actually handle that w/o any problems. if (type == "message") { switch (subtype) { case "disposition-notification": return new MessageDispositionNotification (args); case "delivery-status": return new MessageDeliveryStatus (args); case "partial": if (!IsEncoded (headers)) return new MessagePartial (args); break; case "external-body": case "rfc2822": case "rfc822": case "news": if (!IsEncoded (headers)) return new MessagePart (args); break; } } if (type == "multipart") { switch (subtype) { case "alternative": return new MultipartAlternative (args); case "related": return new MultipartRelated (args); case "report": return new MultipartReport (args); #if ENABLE_CRYPTO case "encrypted": return new MultipartEncrypted (args); case "signed": return new MultipartSigned (args); #endif default: return new Multipart (args); } } if (type == "application") { switch (subtype) { #if ENABLE_CRYPTO case "x-pkcs7-signature": case "pkcs7-signature": return new ApplicationPkcs7Signature (args); case "x-pgp-encrypted": case "pgp-encrypted": return new ApplicationPgpEncrypted (args); case "x-pgp-signature": case "pgp-signature": return new ApplicationPgpSignature (args); case "x-pkcs7-mime": case "pkcs7-mime": return new ApplicationPkcs7Mime (args); #endif case "vnd.ms-tnef": case "ms-tnef": return new TnefPart (args); case "rtf": return new TextPart (args); } } if (type == "text") return new TextPart (args); return new MimePart (args); }
/// <summary> /// Load a <see cref="MimeEntity"/> from the specified content stream. /// </summary> /// <remarks> /// This method is mostly meant for use with APIs such as <see cref="System.Net.HttpWebResponse"/> /// where the headers are parsed separately from the content. /// </remarks> /// <returns>The parsed MIME entity.</returns> /// <param name="contentType">The Content-Type of the stream.</param> /// <param name="content">The content stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="contentType"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="content"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.FormatException"> /// There was an error parsing the entity. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public static MimeEntity Load (ContentType contentType, Stream content, CancellationToken cancellationToken = default (CancellationToken)) { return Load (ParserOptions.Default, contentType, content, cancellationToken); }
static ContentType GetMimeType(string fileName) { var mimeType = MimeTypes.GetMimeType(fileName); return(ContentType.Parse(mimeType)); }
internal static void Encode (StringBuilder builder, ContentType contentType) { Encode (builder, contentType.MediaType); builder.Append (' '); Encode (builder, contentType.MediaSubtype); builder.Append (' '); Encode (builder, contentType.Parameters); }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MimePart"/> class /// with the specified content type. /// </summary> /// <remarks> /// Creates a new <see cref="MimePart"/> with the specified Content-Type value. /// </remarks> /// <param name="contentType">The content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="contentType"/> is <c>null</c>. /// </exception> public MimePart(ContentType contentType) : base(contentType) { }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.MimePart"/> class /// with the specified content type. /// </summary> /// <remarks> /// Creates a new <see cref="MimePart"/> with the specified Content-Type value. /// </remarks> /// <param name="contentType">The content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="contentType"/> is <c>null</c>. /// </exception> public MimePart (ContentType contentType) : base (contentType) { }
static bool TryParse (string text, ref int index, bool multipart, out ContentType contentType) { IList<Parameter> parameters; string type, subtype; contentType = null; while (index < text.Length && text[index] == ' ') index++; if (index >= text.Length) return false; if (!multipart) { if (!TryParse (text, ref index, out type)) return false; } else { type = "multipart"; } if (!TryParse (text, ref index, out subtype)) return false; if (!TryParse (text, ref index, out parameters)) return false; contentType = new ContentType (type, subtype); foreach (var param in parameters) contentType.Parameters.Add (param); return true; }
public void TestEncodingOfLongParamValues() { string encoded, expected; ContentType type; expected = "Content-Type: text/plain; charset=utf-8;\n\tname*0*=iso-8859-1''%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5;\n\tname*1*=%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5%E5;\n\tname*2*=%E5%E5%E5%E5"; type = new ContentType ("text", "plain"); type.Parameters.Add ("charset", "utf-8"); type.Parameters.Add ("name", new string ('å', 40)); encoded = type.ToString (Encoding.UTF8, true); Assert.AreEqual (expected, encoded, "Encoded Content-Type does not match: {0}", expected); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="buffer">The input buffer.</param> /// <param name="startIndex">The starting index of the input buffer.</param> /// <param name="length">The number of bytes in the input buffer to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="buffer"/> is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify /// a valid range in the byte array. /// </exception> public static bool TryParse(byte[] buffer, int startIndex, int length, out ContentType type) { return TryParse (ParserOptions.Default, buffer, startIndex, length, out type); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="options">The parser options.</param> /// <param name="buffer">The input buffer.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="buffer"/> is <c>null</c>.</para> /// </exception> public static bool TryParse(ParserOptions options, byte[] buffer, out ContentType type) { if (options == null) throw new ArgumentNullException ("options"); if (buffer == null) throw new ArgumentNullException ("buffer"); int index = 0; return TryParse (options, buffer, ref index, buffer.Length, false, out type); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the supplied buffer starting at the given index /// and spanning across the specified number of bytes. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="options">The parser options.</param> /// <param name="buffer">The input buffer.</param> /// <param name="startIndex">The starting index of the input buffer.</param> /// <param name="length">The number of bytes in the input buffer to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="buffer"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> and <paramref name="length"/> do not specify /// a valid range in the byte array. /// </exception> public static bool TryParse (ParserOptions options, byte[] buffer, int startIndex, int length, out ContentType type) { ParseUtils.ValidateArguments (options, buffer, startIndex, length); int index = startIndex; return TryParse (options, buffer, ref index, startIndex + length, false, out type); }
internal MimeEntity CreateEntity(ContentType contentType, IList <Header> headers, bool toplevel) { var entity = new MimeEntityConstructorInfo(this, contentType, headers, toplevel); var subtype = contentType.MediaSubtype.ToLowerInvariant(); var type = contentType.MediaType.ToLowerInvariant(); if (mimeTypes.Count > 0) { var mimeType = string.Format("{0}/{1}", type, subtype); ConstructorInfo ctor; if (mimeTypes.TryGetValue(mimeType, out ctor)) { return((MimeEntity)ctor.Invoke(new object[] { entity })); } } // Note: message/rfc822 and message/partial are not allowed to be encoded according to rfc2046 // (sections 5.2.1 and 5.2.2, respectively). Since some broken clients will encode them anyway, // it is necessary for us to treat those as opaque blobs instead, and thus the parser should // parse them as normal MimeParts instead of MessageParts. // // Technically message/disposition-notification is only allowed to have use the 7bit encoding // as well, but since MessageDispositionNotification is a MImePart subclass rather than a // MessagePart subclass, it means that the content won't be parsed until later and so we can // actually handle that w/o any problems. if (type == "message") { switch (subtype) { case "disposition-notification": return(new MessageDispositionNotification(entity)); case "partial": if (!IsEncoded(headers)) { return(new MessagePartial(entity)); } break; case "external-body": case "rfc2822": case "rfc822": case "news": if (!IsEncoded(headers)) { return(new MessagePart(entity)); } break; } } if (type == "multipart") { if (subtype == "related") { return(new MultipartRelated(entity)); } #if ENABLE_CRYPTO if (subtype == "encrypted") { return(new MultipartEncrypted(entity)); } if (subtype == "signed") { return(new MultipartSigned(entity)); } #endif return(new Multipart(entity)); } #if ENABLE_CRYPTO if (type == "application") { switch (subtype) { case "x-pkcs7-signature": case "pkcs7-signature": return(new ApplicationPkcs7Signature(entity)); case "x-pgp-encrypted": case "pgp-encrypted": return(new ApplicationPgpEncrypted(entity)); case "x-pgp-signature": case "pgp-signature": return(new ApplicationPgpSignature(entity)); case "x-pkcs7-mime": case "pkcs7-mime": return(new ApplicationPkcs7Mime(entity)); case "vnd.ms-tnef": case "ms-tnef": return(new TnefPart(entity)); } } #endif if (type == "text") { return(new TextPart(entity)); } return(new MimePart(entity)); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the specified buffer. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="options">The parser options.</param> /// <param name="buffer">The input buffer.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="buffer"/> is <c>null</c>.</para> /// </exception> public static bool TryParse (ParserOptions options, byte[] buffer, out ContentType type) { ParseUtils.ValidateArguments (options, buffer); int index = 0; return TryParse (options, buffer, ref index, buffer.Length, false, out type); }
/// <summary> /// Tries to parse the given text into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the specified text. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="options">THe parser options.</param> /// <param name="text">The text to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="text"/> is <c>null</c>.</para> /// </exception> public static bool TryParse (ParserOptions options, string text, out ContentType type) { ParseUtils.ValidateArguments (options, text); var buffer = Encoding.UTF8.GetBytes (text); int index = 0; return TryParse (options, buffer, ref index, buffer.Length, false, out type); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="options">The parser options.</param> /// <param name="buffer">The input buffer.</param> /// <param name="startIndex">The starting index of the input buffer.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="buffer"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> is out of range. /// </exception> public static bool TryParse(ParserOptions options, byte[] buffer, int startIndex, out ContentType type) { if (options == null) throw new ArgumentNullException ("options"); if (buffer == null) throw new ArgumentNullException ("buffer"); if (startIndex < 0 || startIndex >= buffer.Length) throw new ArgumentOutOfRangeException ("startIndex"); int index = startIndex; return TryParse (options, buffer, ref index, buffer.Length, false, out type); }
/// <summary> /// Tries to parse the given text into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <remarks> /// Parses a Content-Type value from the specified text. /// </remarks> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="text">The text to parse.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="text"/> is <c>null</c>. /// </exception> public static bool TryParse (string text, out ContentType type) { return TryParse (ParserOptions.Default, text, out type); }
/// <summary> /// Tries to parse the given input buffer into a new <see cref="MimeKit.ContentType"/> instance. /// </summary> /// <returns><c>true</c>, if the content type was successfully parsed, <c>false</c> otherwise.</returns> /// <param name="buffer">The input buffer.</param> /// <param name="type">The parsed content type.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="buffer"/> is <c>null</c>. /// </exception> public static bool TryParse(byte[] buffer, out ContentType type) { return TryParse (ParserOptions.Default, buffer, out type); }
static ContentType ParseContentType(ImapEngine engine, CancellationToken cancellationToken) { var type = ReadStringToken (engine, cancellationToken); var subtype = ReadStringToken (engine, cancellationToken); var contentType = new ContentType (type, subtype); var token = engine.ReadToken (cancellationToken); if (token.Type == ImapTokenType.Nil) return contentType; if (token.Type != ImapTokenType.OpenParen) throw ImapEngine.UnexpectedToken (token, false); ParseParameterList (contentType.Parameters, engine, cancellationToken); return contentType; }
internal static bool TryParse(ParserOptions options, byte[] text, ref int index, int endIndex, bool throwOnError, out ContentType contentType) { string type, subtype; int start; contentType = null; if (!ParseUtils.SkipCommentsAndWhiteSpace (text, ref index, endIndex, throwOnError)) return false; start = index; if (!SkipType (text, ref index, endIndex)) { if (throwOnError) throw new ParseException (string.Format ("Invalid type token at position {0}", start), start, index); return false; } type = Encoding.ASCII.GetString (text, start, index - start); if (!ParseUtils.SkipCommentsAndWhiteSpace (text, ref index, endIndex, throwOnError)) return false; if (index >= endIndex || text[index] != (byte) '/') { if (throwOnError) throw new ParseException (string.Format ("Expected '/' at position {0}", index), index, index); return false; } // skip over the '/' index++; if (!ParseUtils.SkipCommentsAndWhiteSpace (text, ref index, endIndex, throwOnError)) return false; start = index; if (!ParseUtils.SkipToken (text, ref index, endIndex)) { if (throwOnError) throw new ParseException (string.Format ("Invalid atom token at position {0}", start), start, index); return false; } subtype = Encoding.ASCII.GetString (text, start, index - start); if (!ParseUtils.SkipCommentsAndWhiteSpace (text, ref index, endIndex, throwOnError)) return false; contentType = new ContentType (type, subtype); if (index >= endIndex) return true; if (text[index] != (byte) ';') { if (throwOnError) throw new ParseException (string.Format ("Expected ';' at position {0}", index), index, index); return false; } index++; if (!ParseUtils.SkipCommentsAndWhiteSpace (text, ref index, endIndex, throwOnError)) return false; if (index >= endIndex) return true; ParameterList parameters; if (!ParameterList.TryParse (options, text, ref index, endIndex, throwOnError, out parameters)) return false; contentType.Parameters = parameters; return true; }
internal static MimeEntity Create(ParserOptions options, ContentType ctype, IEnumerable <Header> headers, bool toplevel) { var entity = new MimeEntityConstructorInfo(options, ctype, headers, toplevel); var subtype = ctype.MediaSubtype.ToLowerInvariant(); var type = ctype.MediaType.ToLowerInvariant(); if (CustomMimeTypes.Count > 0) { var mimeType = string.Format("{0}/{1}", type, subtype); lock (CustomMimeTypes) { ConstructorInfo ctor; if (CustomMimeTypes.TryGetValue(mimeType, out ctor)) { return((MimeEntity)ctor.Invoke(new object[] { entity })); } } } if (type == "message") { if (subtype == "partial") { return(new MessagePartial(entity)); } return(new MessagePart(entity)); } if (type == "multipart") { #if !__MOBILE__ if (subtype == "encrypted") { return(new MultipartEncrypted(entity)); } if (subtype == "signed") { return(new MultipartSigned(entity)); } #endif return(new Multipart(entity)); } #if !__MOBILE__ if (type == "application") { switch (subtype) { case "x-pkcs7-signature": case "pkcs7-signature": return(new ApplicationPkcs7Signature(entity)); case "x-pgp-encrypted": case "pgp-encrypted": return(new ApplicationPgpEncrypted(entity)); case "x-pgp-signature": case "pgp-signature": return(new ApplicationPgpSignature(entity)); case "x-pkcs7-mime": case "pkcs7-mime": return(new ApplicationPkcs7Mime(entity)); } } #endif if (type == "text") { return(new TextPart(entity)); } return(new MimePart(entity)); }