adamdruppe / arsd

This is a collection of modules that I've released over the years. Most of them stand alone, or have just one or two dependencies in here, so you don't have to download this whole repo.
http://arsd-official.dpldocs.info/arsd.html
531 stars 128 forks source link

std.net.curl.CurlException@std\net\curl.d(4402): Failed sending data to the peer on handle 231500 #335

Closed rocex closed 2 years ago

rocex commented 2 years ago
std.net.curl.CurlException@std\net\curl.d(4402): Failed sending data to the peer on handle 231500
----------------
0x00000001400B17AC in pure @safe noreturn std.exception.bailOut!(std.net.curl.CurlException).bailOut(immutable(char)[], ulong, scope const(char)[])
0x000000014008EE82 in pure @safe bool std.exception.enforce!(std.net.curl.CurlException).enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)
0x0000000140067039 in void std.net.curl.Curl._check(int)
0x00000001400675B6 in int std.net.curl.Curl.perform(std.typecons.Flag!("throwOnError").Flag)
0x00000001400669E4 in int std.net.curl.SMTP.perform(std.typecons.Flag!("throwOnError").Flag)
0x000000014004D60D in arsd.email.EmailMessage.send at c:\packages\arsd-official-10.8.4\email.d(316)

window7 x64 dmd v2.098.1-dirty

my code like this

auto message = new EmailMessage();
message.to ~= "abc@defg.com";
message.from = "abc@defg.com";
message.subject = "My Subject";
message.setTextBody("hi there http://www.google.com");
message.addAttachment("text/plain", ".editorconfig", read(".editorconfig"));

message.send(RelayInfo("smtps://mail.defg.com", "user-abc", "#password#"));

https://stackoverflow.com/questions/30289747/how-to-send-e-mail-with-std-net-curl?r=SearchResults

There is an answer on stackoverflow, I noticed Adam D. Ruppe's answer, because there are characters like #$%&* in the password, I think the username should have a similar problem. When I use the same username and password, sending emails with vibe:mail works. Then I saw that vibe:mail encodes the data in Base64 when sending the username and password. So is it possible to also encode the data in arsd:email before sending it? What should I do?

https://github.com/vibe-d/vibe.d/blob/master/mail/vibe/mail/smtp.d line 181 189

final switch (settings.authType) {
    case SMTPAuthType.none: break;
    case SMTPAuthType.plain:
        logDebug("seding auth");
        conn.write("AUTH PLAIN\r\n");
        expectStatus(conn, SMTPStatus.serverAuthReady, "AUTH PLAIN");
        logDebug("seding auth info");
        conn.write(Base64.encode(cast(const(ubyte)[])("\0"~settings.username~"\0"~settings.password)));
        conn.write("\r\n");
        expectStatus(conn, 235, "plain auth info");
        logDebug("authed");
        break;
    case SMTPAuthType.login:
        conn.write("AUTH LOGIN\r\n");
        expectStatus(conn, SMTPStatus.serverAuthReady, "AUTH LOGIN");
        conn.write(Base64.encode(cast(const(ubyte)[])settings.username) ~ "\r\n");
        expectStatus(conn, SMTPStatus.serverAuthReady, "login user name");
        conn.write(Base64.encode(cast(const(ubyte)[])settings.password) ~ "\r\n");
        expectStatus(conn, 235, "login password");
        break;
    case SMTPAuthType.cramMd5: assert(false, "TODO!");
}
rocex commented 2 years ago

I just found out that it is not because there is no encoding, but because the "From" user and the user in "RelayInfo" are not the same cause, and the problem will be solved after changing to the same user.

adamdruppe commented 2 years ago

yeah teh encoding is done by the curl layer. i guess the mail server you are using is just stricter about the from field than some others.

rocex commented 2 years ago

yeah teh encoding is done by the curl layer. i guess the mail server you are using is just stricter about the from field than some others.

So, another question is, what is the maximum file size supported by attachments? When I send a small file, It can send successfully, but when the file size exceeds 100k, the email sending fails. How can I set the maximum file that can be sent?

adamdruppe commented 2 years ago

That depends on the server. I'm pretty gmail's limit is 25 MB, Microsoft's outlook server i think is 5 MB..... you can't set it, the server does it. Check the documentation for your provider to see what their limit is and maybe you can request them to change it.

rocex commented 2 years ago

I'm sure 50MB attachments can be sent when using foxmail, outlook or the web, I feel I'm missing something.

adamdruppe commented 2 years ago

I don't know then, there's no limit in my code. Possible curl has one but I don't think so.... what exact error are you getting?

rocex commented 2 years ago

my code like this:

void mail(string strToList = "", string strSubject = "", string strBodyText = "", string[] strFiles = null)
{
    string[] strToes = split(strToList, ",");

    auto message = new EmailMessage();
    message.from = mailuser ~ maildomain;
    message.subject = strSubject;
    message.setTextBody(strBodyText);

    foreach (strTo; strToes)
    {
        message.addRecipient(strTo, strTo ~ maildomain);
    }

    if (strFiles !is null && strFiles.length > 0)
    {
        string strArchiveFileName = "./archive.zip";

        foreach (strFile; strFiles)
        {
            Zips.zip(strArchiveFileName, strFile);
        }

        message.addAttachment("application/zip", "archive.zip", read(strArchiveFileName));
    }

    message.send(RelayInfo("smtps://" ~ buildConfig.mailhost, buildConfig.mailuser, buildConfig.mailpassword));
}

and then I get this

std.net.curl.CurlException@std\net\curl.d(4402): Failure when receiving data from the peer on handle 589AF0
----------------
0x00000001400F153C in pure @safe noreturn std.exception.bailOut!(std.net.curl.CurlException).bailOut(immutable(char)[], ulong, scope const(char)[])
0x00000001400B2FA2 in pure @safe bool std.exception.enforce!(std.net.curl.CurlException).enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)
0x0000000140076329 in void std.net.curl.Curl._check(int)
0x00000001400768A6 in int std.net.curl.Curl.perform(std.typecons.Flag!("throwOnError").Flag)
0x0000000140075CD4 in int std.net.curl.SMTP.perform(std.typecons.Flag!("throwOnError").Flag)
0x00000001400496FD in arsd.email.EmailMessage.send at E:\Server\DPackages\arsd-official-10.8.4\email.d(316)

when I comment "message.addAttachment("application/zip", "archive.zip", read(strArchiveFileName));", it sent successfully. Yesterday, I could still send attachments, but the size was limited. Today, I can't send attachments. It should be related to our mail server settings. Can we pretend to be a client such as Outlook?

adamdruppe commented 2 years ago

Failure when receiving instead of sending! lol, std.net.curl's errors are so terribly, terribly bad. I should probably stop using it just for that.

But really I have no idea why it is failing here. It is possible I encoded something wrong... but the code is p simple there, it base64 encodes... I don't confirm the boundary doesn't appear in the data, I suppose it is possible that does and that breaks things. But the odds are very low so still more likely it is the server rejecting for some other reason but there's no way for me to know what that is.

Are you trying to send the same attachments as yesterday? If it is the same file it should be the same result...

Can we pretend to be a client such as Outlook?

Email servers can't tell the difference; clients don't identify themselves to it. Only the username+password is told, otherwise the message is the message. A message can include User-Agent but it isn't required and not checked by anything I've seen.

rocex commented 2 years ago

Today I switched the mail service provider to 163.com, and I can send attachments no more than 719kb normally. When this limit is exceeded, one of the following two errors will appear

std.net.curl.CurlException@std\net\curl.d(4402): Failed sending data to the peer on handle 289AF0
----------------
0x00000001400F162C in pure @safe noreturn std.exception.bailOut!(std.net.curl.CurlException).bailOut(immutable(char)[], ulong, scope const(char)[])
0x00000001400B3052 in pure @safe bool std.exception.enforce!(std.net.curl.CurlException).enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)
0x0000000140076289 in void std.net.curl.Curl._check(int)
0x0000000140076806 in int std.net.curl.Curl.perform(std.typecons.Flag!("throwOnError").Flag)
0x0000000140075C34 in int std.net.curl.SMTP.perform(std.typecons.Flag!("throwOnError").Flag)
0x000000014004955D in arsd.email.EmailMessage.send at E:\Server\DPackages\arsd-official-10.8.4\email.d(316)

or

std.net.curl.CurlException@std\net\curl.d(4402): Failure when receiving data from the peer on handle 4F9AF0
----------------
0x00000001400F162C in pure @safe noreturn std.exception.bailOut!(std.net.curl.CurlException).bailOut(immutable(char)[], ulong, scope const(char)[])
0x00000001400B3052 in pure @safe bool std.exception.enforce!(std.net.curl.CurlException).enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong)
0x0000000140076289 in void std.net.curl.Curl._check(int)
0x0000000140076806 in int std.net.curl.Curl.perform(std.typecons.Flag!("throwOnError").Flag)
0x0000000140075C34 in int std.net.curl.SMTP.perform(std.typecons.Flag!("throwOnError").Flag)
0x000000014004955D in arsd.email.EmailMessage.send at E:\Server\DPackages\arsd-official-10.8.4\email.d(316)