async Task MultipartScanEpilogueAsync(Multipart multipart, CancellationToken cancellationToken) { using (var memory = new MemoryStream()) { var result = await ScanContentAsync(memory, true, cancellationToken).ConfigureAwait(false); multipart.RawEpilogue = result.IsEmpty ? null : memory.ToArray(); } }
async Task MultipartScanPreambleAsync(Multipart multipart, CancellationToken cancellationToken) { using (var memory = new MemoryStream()) { await ScanContentAsync(memory, false, cancellationToken).ConfigureAwait(false); multipart.RawPreamble = memory.ToArray(); } }
async Task ConstructMultipartAsync(Multipart multipart, int depth, CancellationToken cancellationToken) { var marker = multipart.Boundary; if (marker == null) { #if DEBUG Debug.WriteLine("Multipart without a boundary encountered!"); #endif // Note: this will scan all content into the preamble... await MultipartScanPreambleAsync(multipart, cancellationToken).ConfigureAwait(false); return; } PushBoundary(marker); await MultipartScanPreambleAsync(multipart, cancellationToken).ConfigureAwait(false); if (boundary == BoundaryType.ImmediateBoundary) { await MultipartScanSubpartsAsync(multipart, depth, cancellationToken).ConfigureAwait(false); } if (boundary == BoundaryType.ImmediateEndBoundary) { // consume the end boundary and read the epilogue (if there is one) multipart.WriteEndBoundary = true; await SkipLineAsync(false, cancellationToken).ConfigureAwait(false); PopBoundary(); await MultipartScanEpilogueAsync(multipart, cancellationToken).ConfigureAwait(false); return; } multipart.WriteEndBoundary = false; // We either found the end of the stream or we found a parent's boundary PopBoundary(); unsafe { fixed(byte *inbuf = input) { if (boundary == BoundaryType.ParentEndBoundary && FoundImmediateBoundary(inbuf, true)) { boundary = BoundaryType.ImmediateEndBoundary; } else if (boundary == BoundaryType.ParentBoundary && FoundImmediateBoundary(inbuf, false)) { boundary = BoundaryType.ImmediateBoundary; } } } }
async Task <BoundaryType> MultipartScanEpilogueAsync(Multipart multipart, CancellationToken cancellationToken) { using (var memory = new MemoryStream()) { var found = await ScanContentAsync(memory, true, cancellationToken).ConfigureAwait(false); multipart.RawEpilogue = found.IsEmpty ? null : memory.ToArray(); return(found.Boundary); } }
async Task <BoundaryType> MultipartScanPreambleAsync(Multipart multipart, CancellationToken cancellationToken) { using (var memory = new MemoryStream()) { var found = await ScanContentAsync(memory, false, cancellationToken).ConfigureAwait(false); multipart.RawPreamble = memory.ToArray(); return(found.Boundary); } }
async Task MultipartScanSubpartsAsync(Multipart multipart, int depth, CancellationToken cancellationToken) { do { // skip over the boundary marker if (!await SkipLineAsync(true, cancellationToken).ConfigureAwait(false)) { boundary = BoundaryType.Eos; return; } // parse the headers state = MimeParserState.Headers; if (await StepAsync(cancellationToken).ConfigureAwait(false) == MimeParserState.Error) { boundary = BoundaryType.Eos; return; } if (state == MimeParserState.Boundary) { if (headers.Count == 0) { if (boundary == BoundaryType.ImmediateBoundary) { continue; } break; } // This part has no content, but that will be handled in ConstructMultipartAsync() // or ConstructMimePartAsync(). } //if (state == ParserState.Complete && headers.Count == 0) // return BoundaryType.EndBoundary; var type = GetContentType(multipart.ContentType); var entity = options.CreateEntity(type, headers, false, depth); if (entity is Multipart) { await ConstructMultipartAsync((Multipart)entity, depth + 1, cancellationToken).ConfigureAwait(false); } else if (entity is MessagePart) { await ConstructMessagePartAsync((MessagePart)entity, depth + 1, cancellationToken).ConfigureAwait(false); } else { await ConstructMimePartAsync((MimePart)entity, cancellationToken).ConfigureAwait(false); } multipart.Add(entity); } while (boundary == BoundaryType.ImmediateBoundary); }
async Task MultipartScanEpilogueAsync(Multipart multipart, CancellationToken cancellationToken) { using (var memory = new MemoryStream()) { long offset = GetOffset(inputIndex); //OnMultipartEpilogueBegin (multipart, offset); var result = await ScanContentAsync(memory, true, cancellationToken).ConfigureAwait(false); multipart.RawEpilogue = result.IsEmpty ? null : memory.ToArray(); //OnMultipartEpilogueEnd (multipart, offset + memory.Length); } }
async Task MultipartScanPreambleAsync(Multipart multipart, CancellationToken cancellationToken) { using (var memory = new MemoryStream()) { long offset = GetOffset(inputIndex); //OnMultipartPreambleBegin (multipart, offset); await ScanContentAsync(memory, false, cancellationToken).ConfigureAwait(false); multipart.RawPreamble = memory.ToArray(); //OnMultipartPreambleEnd (multipart, offset + memory.Length); } }
/// <summary> /// Initialize a new instance of the <see cref="MimeEntityBeginEventArgs"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MimeEntityBeginEventArgs"/>. /// </remarks> /// <param name="entity">The entity that is being parsed.</param> /// <param name="parent">The parent multipart.</param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="parent"/> is <c>null</c>.</para> /// </exception> public MimeEntityBeginEventArgs(MimeEntity entity, Multipart parent) { if (entity == null) { throw new ArgumentNullException(nameof(entity)); } if (parent == null) { throw new ArgumentNullException(nameof(parent)); } Entity = entity; Parent = parent; }
static void Main(string[] args) { var host = "smtp.gmail.com"; var port = 465; var fromAdd = "*****@*****.**"; //送信元アドレス var fromAddPass = "******"; //送信元アドレスパスワード var toAdd = "*****@*****.**"; //送信先アドレス var mailSubject = "エラー通知テスト"; //メールタイトル var mailText = "お疲れ様です。\r\nエラー通知のテストメールを送信いたしまします。"; //メール本文 using (var smtp = new MailKit.Net.Smtp.SmtpClient()) { try { //開発用のSMTPサーバが暗号化に対応していないときは、次の行をコメントアウト //smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto); //認証設定 smtp.Authenticate(fromAdd, fromAddPass); //送信するメールを作成する var mail = new MimeKit.MimeMessage(); var builder = new MimeKit.BodyBuilder(); mail.From.Add(new MimeKit.MailboxAddress("", fromAdd)); mail.To.Add(new MimeKit.MailboxAddress("", toAdd)); //メールタイトル mail.Subject = mailSubject; //メール本文 MimeKit.TextPart textPart = new MimeKit.TextPart("Plain"); textPart.Text = mailText; var multipart = new MimeKit.Multipart("mixed"); multipart.Add(textPart); mail.Body = multipart; //メールを送信する smtp.Send(mail); } catch (Exception exception) { Console.WriteLine(exception.Message); } finally { //SMTPサーバから切断する smtp.Disconnect(true); } } }
async Task <BoundaryType> MultipartScanSubpartsAsync(Multipart multipart, CancellationToken cancellationToken) { BoundaryType found; do { // skip over the boundary marker if (!await SkipLineAsync(true, cancellationToken).ConfigureAwait(false)) { return(BoundaryType.Eos); } // parse the headers state = MimeParserState.Headers; if (await StepAsync(cancellationToken).ConfigureAwait(false) == MimeParserState.Error) { return(BoundaryType.Eos); } //if (state == ParserState.Complete && headers.Count == 0) // return BoundaryType.EndBoundary; var type = GetContentType(multipart.ContentType); var entity = options.CreateEntity(type, headers, false); if (entity is Multipart) { found = await ConstructMultipartAsync((Multipart)entity, cancellationToken).ConfigureAwait(false); } else if (entity is MessagePart) { found = await ConstructMessagePartAsync((MessagePart)entity, cancellationToken).ConfigureAwait(false); } else { found = await ConstructMimePartAsync((MimePart)entity, cancellationToken).ConfigureAwait(false); } multipart.Add(entity); } while (found == BoundaryType.ImmediateBoundary); return(found); }
/// <summary> /// Visit the abstract multipart MIME entity. /// </summary> /// <remarks> /// Visits the abstract multipart MIME entity. /// </remarks> /// <param name="multipart">The multipart MIME entity.</param> protected internal virtual void VisitMultipart(Multipart multipart) { VisitMimeEntity(multipart); VisitChildren(multipart); }
/// <summary> /// Constructs the message body based on the text-based bodies, the linked resources, and the attachments. /// </summary> /// <remarks> /// Combines the <see cref="Attachments"/>, <see cref="LinkedResources"/>, <see cref="TextBody"/>, /// and <see cref="HtmlBody"/> into the proper MIME structure suitable for display in many common /// mail clients. /// </remarks> /// <returns>The message body.</returns> public MimeEntity ToMessageBody() { MultipartAlternative alternative = null; MimeEntity body = null; if (!string.IsNullOrEmpty(TextBody)) { var text = new TextPart("plain"); text.Text = TextBody; if (!string.IsNullOrEmpty(HtmlBody)) { alternative = new MultipartAlternative(); alternative.Add(text); body = alternative; } else { body = text; } } if (!string.IsNullOrEmpty(HtmlBody)) { var text = new TextPart("html"); MimeEntity html; text.ContentId = MimeUtils.GenerateMessageId(); text.Text = HtmlBody; if (LinkedResources.Count > 0) { var related = new MultipartRelated { Root = text }; foreach (var resource in LinkedResources) { related.Add(resource); } html = related; } else { html = text; } if (alternative != null) { alternative.Add(html); } else { body = html; } } if (Attachments.Count > 0) { var mixed = new Multipart("mixed"); if (body != null) { mixed.Add(body); } foreach (var attachment in Attachments) { mixed.Add(attachment); } body = mixed; } return(body ?? new TextPart("plain") { Text = string.Empty }); }
async Task ConstructMultipartAsync(Multipart multipart, MimeEntityEndEventArgs args, int depth, CancellationToken cancellationToken) { var beginOffset = GetOffset(inputIndex); var beginLineNumber = lineNumber; var marker = multipart.Boundary; long endOffset; if (marker == null) { #if DEBUG Debug.WriteLine("Multipart without a boundary encountered!"); #endif // Note: this will scan all content into the preamble... await MultipartScanPreambleAsync(multipart, cancellationToken).ConfigureAwait(false); endOffset = GetEndOffset(inputIndex); args.Lines = GetLineCount(beginLineNumber, beginOffset, endOffset); return; } PushBoundary(marker); await MultipartScanPreambleAsync(multipart, cancellationToken).ConfigureAwait(false); if (boundary == BoundaryType.ImmediateBoundary) { await MultipartScanSubpartsAsync(multipart, depth, cancellationToken).ConfigureAwait(false); } if (boundary == BoundaryType.ImmediateEndBoundary) { //OnMultipartEndBoundaryBegin (multipart, GetEndOffset (inputIndex)); // consume the end boundary and read the epilogue (if there is one) multipart.WriteEndBoundary = true; await SkipLineAsync(false, cancellationToken).ConfigureAwait(false); PopBoundary(); //OnMultipartEndBoundaryEnd (multipart, GetOffset (inputIndex)); await MultipartScanEpilogueAsync(multipart, cancellationToken).ConfigureAwait(false); endOffset = GetEndOffset(inputIndex); args.Lines = GetLineCount(beginLineNumber, beginOffset, endOffset); return; } endOffset = GetEndOffset(inputIndex); args.Lines = GetLineCount(beginLineNumber, beginOffset, endOffset); multipart.WriteEndBoundary = false; // We either found the end of the stream or we found a parent's boundary PopBoundary(); unsafe { fixed(byte *inbuf = input) { if (boundary == BoundaryType.ParentEndBoundary && FoundImmediateBoundary(inbuf, true)) { boundary = BoundaryType.ImmediateEndBoundary; } else if (boundary == BoundaryType.ParentBoundary && FoundImmediateBoundary(inbuf, false)) { boundary = BoundaryType.ImmediateBoundary; } } } }
async Task MultipartScanSubpartsAsync(Multipart multipart, int depth, CancellationToken cancellationToken) { //var beginOffset = GetOffset (inputIndex); do { //OnMultipartBoundaryBegin (multipart, beginOffset); // skip over the boundary marker if (!await SkipLineAsync(true, cancellationToken).ConfigureAwait(false)) { //OnMultipartBoundaryEnd (multipart, GetOffset (inputIndex)); boundary = BoundaryType.Eos; return; } //OnMultipartBoundaryEnd (multipart, GetOffset (inputIndex)); var beginLineNumber = lineNumber; // parse the headers state = MimeParserState.Headers; if (await StepAsync(cancellationToken).ConfigureAwait(false) == MimeParserState.Error) { boundary = BoundaryType.Eos; return; } if (state == MimeParserState.Boundary) { if (headers.Count == 0) { if (boundary == BoundaryType.ImmediateBoundary) { //beginOffset = GetOffset (inputIndex); continue; } return; } // This part has no content, but that will be handled in ConstructMultipartAsync() // or ConstructMimePartAsync(). } //if (state == ParserState.Complete && headers.Count == 0) // return BoundaryType.EndBoundary; var type = GetContentType(multipart.ContentType); var entity = options.CreateEntity(type, headers, false, depth); var entityArgs = new MimeEntityEndEventArgs(entity, multipart) { HeadersEndOffset = headerBlockEnd, BeginOffset = headerBlockBegin, LineNumber = beginLineNumber }; OnMimeEntityBegin(entityArgs); if (entity is Multipart) { await ConstructMultipartAsync((Multipart)entity, entityArgs, depth + 1, cancellationToken).ConfigureAwait(false); } else if (entity is MessagePart) { await ConstructMessagePartAsync((MessagePart)entity, entityArgs, depth + 1, cancellationToken).ConfigureAwait(false); } else { await ConstructMimePartAsync((MimePart)entity, entityArgs, cancellationToken).ConfigureAwait(false); } var endOffset = GetEndOffset(inputIndex); entityArgs.HeadersEndOffset = Math.Min(entityArgs.HeadersEndOffset, endOffset); entityArgs.EndOffset = endOffset; OnMimeEntityEnd(entityArgs); //beginOffset = endOffset; multipart.Add(entity); } while (boundary == BoundaryType.ImmediateBoundary); }
/// <summary> /// Initialize a new instance of the <see cref="MimeEntityEndEventArgs"/> class. /// </summary> /// <remarks> /// Creates a new <see cref="MimeEntityEndEventArgs"/>. /// </remarks> /// <param name="entity">The entity that was parsed.</param> /// <param name="parent">The parent multipart.</param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="parent"/> is <c>null</c>.</para> /// </exception> public MimeEntityEndEventArgs(MimeEntity entity, Multipart parent) : base(entity, parent) { }