Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
SMTP + Anhänge in Container (Alpine)
Campy
myCSharp.de - Member



Dabei seit:
Beiträge: 414

Themenstarter:

SMTP + Anhänge in Container (Alpine)

beantworten | zitieren | melden

Hallo zusammen,

ich habe folgenden Code der in einem Docker Container (mcr.microsoft.com/dotnet/runtime:5.0-alpine3.12-amd64) zum Versenden von E-Mails ausgeführt wird:
(Ich weiß, der Code ist noch nicht optimal aber habe ihn in ein Testprojekt kopiert.


var message = new MimeMessage();
                message.From.Add(new MailboxAddress(email.SenderName.Length > 0 ? email.SenderName : Parameters["Sendername"],
                    email.SenderEmail.Length > 0 ? email.SenderEmail : Parameters["Sender"]));

                var recipients = new List<string>();
                var ccRecipients = new List<string>();
                var bccRecipients = new List<string>();

                if (!string.IsNullOrEmpty(email.Recipients))
                    recipients = new List<string>(email.Recipients.Split(";".ToCharArray()));

                if (!string.IsNullOrEmpty(email.RecipientsCC))
                    ccRecipients = new List<string>(email.RecipientsCC.Split(";".ToCharArray()));

                if (!string.IsNullOrEmpty(email.RecipientsBCC))
                    bccRecipients = new List<string>(email.RecipientsBCC.Split(";".ToCharArray()));

                if (bccRecipients != null)
                {
                    foreach (string bccRecipient in bccRecipients)
                        if (!string.IsNullOrEmpty(bccRecipient))
                            message.Bcc.Add(MailboxAddress.Parse(bccRecipient));
                }

                if (ccRecipients != null)
                {
                    foreach (string ccRecipient in ccRecipients)
                        if (!string.IsNullOrEmpty(ccRecipient))
                            message.Cc.Add(MailboxAddress.Parse(ccRecipient));
                }

                if (recipients != null)
                {
                    foreach (string Recipient in recipients)
                        if (!string.IsNullOrEmpty(Recipient))
                            message.Cc.Add(MailboxAddress.Parse(Recipient));
                }

                message.Subject = email.Subject;

                var body = new TextPart("plain")
                {
                    Text = email.Body
                };

                var multipart = new Multipart("mixed");
                multipart.Add(body);
                
                if (email.Attachment1 != null)
                {
                    var attachment1 = new MimePart("application", "pdf")
                    {
                        Content = new MimeContent(new MemoryStream(email.Attachment1), ContentEncoding.Default),
                        ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                        ContentTransferEncoding = ContentEncoding.Base64,
                        FileName = email.Attachment1Name
                    };
                    multipart.Add(attachment1);
                }

                // now set the multipart/mixed as the message body
                message.Body = multipart;

                try
                {
                    using (var client = new SmtpClient())
                    {
                        client.Connect(server, 25, false);

                        // Note: only needed if the SMTP server requires authentication
                        if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
                            client.Authenticate(username, password);

                        client.Send(message);
                        client.Disconnect(true);
                    }

                    _logger.LogDebug("Die E-Mail {mailid} wurde erfolgreich versendet", email.Id);
                    email.Success = true;
                }
                catch(Exception ex)
                {
                    _logger.LogError(ex, "Fehler beim Versenden der E-Mail {mailid}", email.Id);
                }
                finally
                {
                    email.RetryCount = email.RetryCount + 1;
                    _logger.LogDebug("Neuer RetryCount für E-Mail {maild} beträgt {retrycount}", email.Id, email.RetryCount);
                    email.LastTry = DateTime.Now;

                    if (emailProxy.Put(email))
                        _logger.LogDebug("Die E-Mail wurde erfolgreich aktualisiert");
                    else
                        _logger.LogError("Fehler beim Speichern der Änderungen der E-Mail");
                }

Das ganze funktioniert nun im Docker Container, solange Anhang1 nicht zwei Bilder enthält (Dateigröße gute 50kb)..
Starte ich die Anwendung unter Windows, gleicher SMTP Server und gleiche Datenbank, funktioniert es sofort.

Hat jemand eine Idee? Sollte ich mal ein Ubuntu Image probieren?

Vielen Dank!
A programmer is just a tool, which converts coffeine into code!
private Nachricht | Beiträge des Benutzers
Campy
myCSharp.de - Member



Dabei seit:
Beiträge: 414

Themenstarter:

beantworten | zitieren | melden

Habs nun mit einem aktuellen Ubuntu getestet - funktioniert ebenso nicht.

Fehler
System.IO.IOException: Connection timed out
---> System.Net.Sockets.SocketException (110): Connection timed out
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at MailKit.Net.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
--- End of inner exception stack trace ---
at MailKit.Net.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at MailKit.Net.Smtp.SmtpStream.ReadAheadAsync(Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Smtp.SmtpStream.ReadResponseAsync(Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Smtp.SmtpStream.ReadResponse(CancellationToken cancellationToken)
at MailKit.Net.Smtp.SmtpClient.DataAsync(FormatOptions options, MimeMessage message, Int64 size, Boolean doAsync, CancellationToken cancellationToken, ITransferProgress progress)
at MailKit.Net.Smtp.SmtpClient.SendAsync(FormatOptions options, MimeMessage message, MailboxAddress sender, IList`1 recipients, Boolean doAsync, CancellationToken cancellationToken, ITransferProgress progress)
at MailKit.Net.Smtp.SmtpClient.Send(FormatOptions options, MimeMessage message, CancellationToken cancellationToken, ITransferProgress progress)

Der Logoutput vom Postfix Relay sieht so aus:
Fehler
Mar 18 08:21:00 postfix/smtpd[814]: connect from unknown[172.16.3.4]
Mar 18 08:21:00 postfix/smtpd[814]: B76D31A0A3F: client=unknown[172.16.3.4]
Mar 18 08:21:00 postfix/cleanup[815]: B76D31A0A3F: message-id=<[email protected]>
Mar 18 08:23:00 postfix/smtpd[630]: timeout after DATA (65713 bytes) from unknown[172.16.3.4]
Mar 18 08:23:00 postfix/smtpd[630]: disconnect from unknown[172.16.3.4] ehlo=1 mail=1 rcpt=1 data=0/1 commands=3/4

Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Campy am .
A programmer is just a tool, which converts coffeine into code!
private Nachricht | Beiträge des Benutzers
dannoe
myCSharp.de - Member



Dabei seit:
Beiträge: 151

beantworten | zitieren | melden

Wenn man Probleme mit einer Library hat einfach mal in den Github Issues der Library suchen.
Auf die schnelle hab ich das hier gefunden: https://github.com/jstedfast/MailKit/issues/1157
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dannoe am .
private Nachricht | Beiträge des Benutzers
Campy
myCSharp.de - Member



Dabei seit:
Beiträge: 414

Themenstarter:

beantworten | zitieren | melden

Ja da hast du Recht - ich habs sogar schon mit System.Net.Mail probiert gehabt (einfach mal einen Schritt zurück) aber auch da kam der gleiche Fehler
A programmer is just a tool, which converts coffeine into code!
private Nachricht | Beiträge des Benutzers
dannoe
myCSharp.de - Member



Dabei seit:
Beiträge: 151

beantworten | zitieren | melden

Der Autor der Library vermutet "probably a .NET Core runtime bug on Linux". Wenn das tatäschlich so ist, dann bringen dir leider auch andere Libraries nichts, sofern diese auf der gleichen Basis aufsetzen.
private Nachricht | Beiträge des Benutzers
Campy
myCSharp.de - Member



Dabei seit:
Beiträge: 414

Themenstarter:

beantworten | zitieren | melden

Zitat von dannoe
Der Autor der Library vermutet "probably a .NET Core runtime bug on Linux". Wenn das tatäschlich so ist, dann bringen dir leider auch andere Libraries nichts, sofern diese auf der gleichen Basis aufsetzen.

Was halt komisch ist und bleibt, das Problem besteht überhaupt nicht, wenn keine Anhänge angehängt wurden, und auch nur bei einem Teil von Anhängen..
A programmer is just a tool, which converts coffeine into code!
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Campy, naja; die Fehlermeldung zeigt einen Socket-Fehler beim Ressounrcezugriff.
Wenn Du keine Attachments verlinkst, wird eben das Zeug auch nicht ausgeführt; ergo ist der Bug wohl egal, wenn Du keine Attachments hast.

Kannst Du mal bisschen mehr Infos geben wie zB: wo liegen die Ressourcen? Worin unterscheiden sich Ressourcen, die funktionieren und die nicht funktionieren?
Ansonsten einfach mal MailKit Source ziehen und selbst debuggen; das is ja das schöne an Open Source.
private Nachricht | Beiträge des Benutzers
Campy
myCSharp.de - Member



Dabei seit:
Beiträge: 414

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt
Campy, naja; die Fehlermeldung zeigt einen Socket-Fehler beim Ressounrcezugriff.
Wenn Du keine Attachments verlinkst, wird eben das Zeug auch nicht ausgeführt; ergo ist der Bug wohl egal, wenn Du keine Attachments hast.

Ja das stimmt, jedoch funktioniert ein Teil (alle sind PDFs die vom gleichen Generator generiert wurden).
Zitat von Abt
Kannst Du mal bisschen mehr Infos geben wie zB: wo liegen die Ressourcen? Worin unterscheiden sich Ressourcen, die funktionieren und die nicht funktionieren?
Ansonsten einfach mal MailKit Source ziehen und selbst debuggen; das is ja das schöne an Open Source.

Die E-Mails liegen in einer Datenbank (postgresql) als bytea (byte[]) und werden per WebApi Dienst abgeholt


        private byte[] _Attachment1;
        public virtual byte[] Attachment1
        {
            get { return _Attachment1; }
            set { _Attachment1 = value; NotifyPropertyChanged("Attachment1"); }
        }

So wird es an Mailkit übergeben:


 var body = new TextPart("plain")
                {
                    Text = email.Body
                };

                var multipart = new Multipart("mixed");
                multipart.Add(body);
                
                if (email.Attachment1 != null)
                {
                    var attachment1 = new MimePart("application", "pdf")
                    {
                        Content = new MimeContent(new MemoryStream(email.Attachment1), ContentEncoding.Default),
                        ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                        ContentTransferEncoding = ContentEncoding.Base64,
                        FileName = email.Attachment1Name
                    };
                    multipart.Add(attachment1);
                }

                // now set the multipart/mixed as the message body
                message.Body = multipart;

Hast du einen Tipp wie ich es am besten Debuggen könnte, da der Fehler nur im Docker Container besteht obwohl alle Rahmenparameter sonst die Gleichen sind.
Führe ich die Anwendung bei mir unter Windows aus funktioniert es sofort problemlos..

Danke im Voraus!


A programmer is just a tool, which converts coffeine into code!
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Hast Du Dir überhaupt mal den GitHub Issue durchgelesen, der für den Fehler verantwortlich sein könnte?
Da steht ja klar, dass es eine Race Condition / Safety des Threads ist.

Das heisst, dass der Fehler auftreten kann, aber nicht muss. Ergo kann das bei einem File auftreten; muss aber nicht.
Es kann bei File A auftreten, aber bei B nicht. Oder bei beidem. Oder bei keinem.

Zitat
WebApi Dienst
Web Api ist ein Produkt. Was du meinst ist eine Http Api.
Aber das ist nur Wording.


Du kannst in MailKit auch Attachments direkt als Byte übergeben, ohne explizit ein MemoryStream verwenden zu müssen.
Aber da unbekannt ist, wer für den Socket-Error verantwortlich ist heisst das nicht, dass es dann geht..
Zitat
da der Fehler nur im Docker Container besteht
Vorhin hast noch gesagt es gibt den Error auch unter Ubuntu; und den Fehler gibts offenbar auf alle Linux-Varianten.
Dann verwende doch einfach Docker lokal zum Debuggen oder die WSL. Wo ist das Problem?
Debug Your .NET Core Apps in WSL 2 with Visual Studio | .NET Blog


private Nachricht | Beiträge des Benutzers
Campy
myCSharp.de - Member



Dabei seit:
Beiträge: 414

Themenstarter:

beantworten | zitieren | melden

Danke Abt, ich konnte das Projekt auch erfolgreich und ohne Probleme unter WSL debuggen.
Da es auch dort ohne Probleme lief, haben wir uns weiter auf die Suche gemacht =>

Es lag wohl am Zusammenspiel von Docker Port-Mappings des Relay Containers und der OpnSense Firewall die eingesetzt wird.
Eigentlich befinden sich die SMTP-Container und der Relay Container im gleichen Netzwerk - durch das PortMapping hat das Docker anscheinend anders geroutet und so lag die OpnSense dazwischen. Komisch und fragwürdig bleibt nur, wieso dies erst beim überschreiten der MTU Size geblockt hat.
A programmer is just a tool, which converts coffeine into code!
private Nachricht | Beiträge des Benutzers