-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Needs more than 40 seconds to send. Any ideas why? #26
Comments
It's very strange, but I think you have some network delay, try to put the router and device close. |
Maybe the delay is on the line If the server sends fewer outputs, it still waits for 6. I will change the code on my end to stop the loop when there is a call with a delay occuring, and see if it helps on my end. |
Hi @salasidis, |
When I use a Gmail address it sends within 2s. It isn't caused by network delay. I send it only once when battery is low so I can live with those 40 seconds. |
Hi Ben,
https://github.com/xreef/EMailSender/blob/master/EMailSenderKey.h#L43 Bye Renzo |
`............................... EHLO WemosSensor: 250-8BITMIME 250-AUTH LOGIN PLAIN 250 SIZE 69920427 AUTH LOGIN: Encoding Encoding MAIL FROM: *hidden*@gmx.net RCPT TO: *hidden*@gmx.ch DATA: Message end 221 gmx.net Service closing transmission channel Sending status: |
There is a point that needs more time? |
After "250 SIZE 69920427" starts the delay until "AUTH LOGIN:". Hope that helps |
I played a bit around and changed the loop to 2: 221 gmx.net Service closing transmission channel Sending status: Looks like salasidis was right! |
I added a test code on my end,
I time the rime between successive 250-×××
If the time of any one is greater than a few seconds, I presume there are no more left, and I proceed to an auth login
This way the delay happens just once, and is independent of the number of 250×× replies from the server.
Otherwise there wad a risk of interviewing the 250××× responses with the auth login going out, or too long delay, if exoect more 250s than there actually are.
…-------- Original message --------
From: BenSeventy9 ***@***.***>
Date: 2022-07-01 08:39 (GMT-05:00)
To: xreef/EMailSender ***@***.***>
Cc: rsalasidis ***@***.***>, Mention ***@***.***>
Subject: Re: [xreef/EMailSender] Needs more than 40 seconds to send. Any ideas why? (Issue #26)
After "250 SIZE 69920427" starts the delay until "AUTH LOGIN:". Hope that helps
—
Reply to this email directly, view it on GitHub<#26 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AK5VYZODOIQ3U7PURPV3OFDVR3RHHANCNFSM5ZMZRLZQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Do you have some code snipped for me? |
In emailSender.cpp I did the following. I also attached the whole file.
Let me know if helpful. Thanks
response = awaitSMTPResponse(client, "220", "Connection Error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
String commandHELO = "HELO";
if (this->useEHLO == true) {
commandHELO = "EHLO";
}
String helo = commandHELO + " "+/*String(publicIPDescriptor)*/ smtp_server /*+": "*/;
DEBUG_PRINTLN(helo);
client.println(helo);
response = awaitSMTPResponse(client, "250", "Identification error");
DEBUG_PRINTLN(response.status);
if (!response.status) {
client.flush();
client.stop();
return response;
}
loopTime1 = millis();
DEBUG_PRINTLN(loopTime1);
if (this->useEHLO == true) {
for (int i = 0; i<=20; i++) {
awaitSMTPResponse(client);
loopTime2 = millis();
DEBUG_PRINTLN(loopTime2);
if ((loopTime2 - loopTime1) > 2500) {
break;
} else {
loopTime1 = loopTime2;
}
}
}
DEBUG_PRINTLN("End of awaitSMTPResponse");
From: BenSeventy9 ***@***.***>
Sent: July 1, 2022 16:04
To: xreef/EMailSender ***@***.***>
Cc: rsalasidis ***@***.***>; Mention ***@***.***>
Subject: Re: [xreef/EMailSender] Needs more than 40 seconds to send. Any ideas why? (Issue #26)
I added a test code on my end, I time the rime between successive 250-××× If the time of any one is greater than a few seconds, I presume there are no more left, and I proceed to an auth login This way the delay happens just once, and is independent of the number of 250×× replies from the server. Otherwise there wad a risk of interviewing the 250××× responses with the auth login going out, or too long delay, if exoect more 250s than there actually are.
Do you have some code snipped for me?
—
Reply to this email directly, view it on GitHub<#26 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AK5VYZMGWYZLF4SOYO4YXF3VR5FMFANCNFSM5ZMZRLZQ>.
You are receiving this because you were mentioned.Message ID: ***@***.******@***.***>>
/*
* EMail Sender Arduino, esp8266 and esp32 library to send email
*
* AUTHOR: Renzo Mischianti
* VERSION: 3.0.0
*
* https://www.mischianti.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
*
* You may copy, alter and reuse this code in any way you like, but please leave
* reference to www.mischianti.org in your comments if you redistribute this code.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "EMailSender.h"
#include <stdio.h>
//#include <SPIFFS.h>
//#include <LittleFS.h>
//#define SD SPIFFS
// BASE64 -----------------------------------------------------------
const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
#define encode64(arr) encode64_f(arr,strlen(arr))
inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
int base64_encode(char *output, char *input, int inputLen) {
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--) {
a3[i++] = *(input++);
if (i == 3) {
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
}
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
}
while ((i++ < 3)) {
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
int base64_enc_length(int plainLen) {
int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
const char* encode64_f(char* input, uint8_t len) {
// encoding
DEBUG_PRINTLN(F("Encoding"));
DEBUG_PRINTLN(input);
DEBUG_PRINTLN(len);
//int encodedLen =
base64_enc_length(len);
static char encoded[256];
// note input is consumed in this step: it will be empty afterwards
base64_encode(encoded, input, len);
return encoded;
}
// END BASE64 ---------------------------------------------------------
EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* name_from ,
const char* smtp_server, uint16_t smtp_port) {
this->setEMailLogin(email_login);
this->setEMailFrom(email_from);
this->setEMailPassword(email_password);
this->setSMTPServer(smtp_server);
this->setSMTPPort(smtp_port);
this->setNameFrom(name_from);
// this->isSecure = isSecure;
}
EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from,
const char* smtp_server, uint16_t smtp_port) {
this->setEMailLogin(email_login);
this->setEMailFrom(email_from);
this->setEMailPassword(email_password);
this->setSMTPServer(smtp_server);
this->setSMTPPort(smtp_port);
// this->isSecure = isSecure;
}
EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from, const char* name_from ) {
this->setEMailLogin(email_login);
this->setEMailFrom(email_from);
this->setEMailPassword(email_password);
this->setNameFrom(name_from);
this->setNameFrom(name_from);
// this->isSecure = isSecure;
}
EMailSender::EMailSender(const char* email_login, const char* email_password, const char* email_from) {
this->setEMailLogin(email_login);
this->setEMailFrom(email_from);
this->setEMailPassword(email_password);
// this->isSecure = isSecure;
}
EMailSender::EMailSender(const char* email_login, const char* email_password){
this->setEMailLogin(email_login);
this->setEMailFrom(email_login);
this->setEMailPassword(email_password);
// this->isSecure = isSecure;
}
void EMailSender::setSMTPPort(uint16_t smtp_port){
this->smtp_port = smtp_port;
};
void EMailSender::setSMTPServer(const char* smtp_server){
delete [] this->smtp_server;
this->smtp_server = new char[strlen(smtp_server)+1];
strcpy(this->smtp_server, smtp_server);
};
void EMailSender::setEMailLogin(const char* email_login){
delete [] this->email_login;
this->email_login = new char[strlen(email_login)+1];
strcpy(this->email_login, email_login);
};
void EMailSender::setEMailFrom(const char* email_from){
delete [] this->email_from;
this->email_from = new char[strlen(email_from)+1];
strcpy(this->email_from, email_from);
};
void EMailSender::setNameFrom(const char* name_from){
delete [] this->name_from;
this->name_from = new char[strlen(name_from)+1];
strcpy(this->name_from, name_from);
};
void EMailSender::setEMailPassword(const char* email_password){
delete [] this->email_password;
this->email_password = new char[strlen(email_password)+1];
strcpy(this->email_password, email_password);
};
void EMailSender::setIsSecure(bool isSecure) {
this->isSecure = isSecure;
}
#ifdef SSLCLIENT_WRAPPER
EMailSender::Response EMailSender::awaitSMTPResponse(SSLClient &client,
const char* resp, const char* respDesc, uint16_t timeOut) {
EMailSender::Response response;
uint32_t ts = millis();
while (!client.available()) {
if (millis() > (ts + timeOut)) {
response.code = F("1");
response.desc = String(respDesc) + "! " + F("SMTP Response TIMEOUT!");
response.status = false;
return response;
}
}
_serverResponce = client.readStringUntil('\n');
DEBUG_PRINTLN(_serverResponce);
if (resp && _serverResponce.indexOf(resp) == -1){
response.code = resp;
response.desc = respDesc +String(" (") + _serverResponce + String(")");
response.status = false;
return response;
}
response.status = true;
return response;
}
#else
EMailSender::Response EMailSender::awaitSMTPResponse(EMAIL_NETWORK_CLASS &client,
const char* resp, const char* respDesc, uint16_t timeOut) {
EMailSender::Response response;
uint32_t ts = millis();
while (!client.available()) {
if (millis() > (ts + timeOut)) {
response.code = F("1");
response.desc = String(respDesc) + "! " + F("SMTP Response TIMEOUT!");
response.status = false;
return response;
}
}
_serverResponce = client.readStringUntil('\n');
DEBUG_PRINTLN("Server Response = ");
DEBUG_PRINTLN(_serverResponce);
if (resp && _serverResponce.indexOf(resp) == -1){
response.code = resp;
response.desc = respDesc +String(" (") + _serverResponce + String(")");
response.status = false;
return response;
}
response.status = true;
return response;
}
#endif
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void encodeblock(unsigned char in[3],unsigned char out[4],int len) {
out[0]=cb64[in[0]>>2]; out[1]=cb64[((in[0]&0x03)<<4)|((in[1]&0xF0)>>4)];
out[2]=(unsigned char) (len>1 ? cb64[((in[1]&0x0F)<<2)|((in[2]&0xC0)>>6)] : '=');
out[3]=(unsigned char) (len>2 ? cb64[in[2]&0x3F] : '=');
}
#ifdef ENABLE_ATTACHMENTS
#ifdef STORAGE_EXTERNAL_ENABLED
#if (defined(DIFFERENT_FILE_MANAGE) && defined(EMAIL_FILE_EX)) || !defined(STORAGE_INTERNAL_ENABLED)
#ifdef SSLCLIENT_WRAPPER
void encode(EMAIL_FILE_EX *file, SSLClient *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#else
void encode(EMAIL_FILE_EX *file, EMAIL_NETWORK_CLASS *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#endif
#endif
#endif
#ifdef STORAGE_INTERNAL_ENABLED
#if defined(DIFFERENT_FILE_MANAGE) || (!defined(DIFFERENT_FILE_MANAGE) && defined(EMAIL_FILE)) || !defined(STORAGE_EXTERNAL_ENABLED)
#ifdef SSLCLIENT_WRAPPER
void encode(EMAIL_FILE *file, SSLClient *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#else
void encode(EMAIL_FILE *file, EMAIL_NETWORK_CLASS *client) {
unsigned char in[3],out[4];
int i,len,blocksout=0;
while (file->available()!=0) {
len=0;
for (i=0;i<3;i++){
in[i]=(unsigned char) file->read();
if (file->available()!=0) len++;
else in[i]=0;
}
if (len){
encodeblock(in,out,len);
// for(i=0;i<4;i++) client->write(out[i]);
client->write(out, 4);
blocksout++; }
if (blocksout>=19||file->available()==0){
if (blocksout) {
client->print("\r\n");
}
blocksout=0;
}
}
}
#endif
#endif
#endif
#endif
const char** toCharArray(String arr[], int num) {
// If we ever alloc with new with have to delete
const char** buffer = new const char*[num];
for(int i = 0; i < num; i++) {
buffer[i] = arr[i].c_str();
}
return buffer;
}
const char** toCharArray(char* arr[], int num) {
// If we ever alloc with new with have to delete
const char** buffer = new const char*[num];
for(int i = 0; i < num; i++) {
buffer[i] = arr[i];
}
return buffer;
}
EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, EMailMessage &email, Attachments attachments) {
return send(toCharArray(tos, sizeOfTo), sizeOfTo, 0, 0, email, attachments);
}
EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) {
return send(toCharArray(tos, sizeOfTo+sizeOfCc), sizeOfTo, sizeOfCc, 0, email, attachments);
}
EMailSender::Response EMailSender::send(char* tos[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments){
return send(toCharArray(tos, sizeOfTo+sizeOfCc+sizeOfCCn), sizeOfTo, sizeOfCc, sizeOfCCn, email, attachments);
}
EMailSender::Response EMailSender::send(String to, EMailMessage &email, Attachments attachments){
DEBUG_PRINT(F("ONLY ONE RECIPIENT"));
const char* arrEmail[] = {to.c_str()};
return send(arrEmail, 1, email, attachments);
}
EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, EMailMessage &email, Attachments attachments) {
return send(toCharArray(tos, sizeOfTo), sizeOfTo, 0, 0, email, attachments);
}
EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments) {
return send(toCharArray(tos, sizeOfTo+sizeOfCc), sizeOfTo, sizeOfCc, 0, email, attachments);
}
EMailSender::Response EMailSender::send(String tos[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments){
return send(toCharArray(tos, sizeOfTo+sizeOfCc+sizeOfCCn), sizeOfTo, sizeOfCc, sizeOfCCn, email, attachments);
}
EMailSender::Response EMailSender::send(const char* to, EMailMessage &email, Attachments attachments){
DEBUG_PRINT(F("ONLY ONE RECIPIENT"));
const char* arrEmail[] = {to};
return send(arrEmail, 1, email, attachments);
}
EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, EMailMessage &email, Attachments attachments) {
DEBUG_PRINTLN(F("miltiple destination and attachments"));
return send(to, sizeOfTo, 0, email, attachments);
}
EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte sizeOfCc, EMailMessage &email, Attachments attachments)
{
return send(to, sizeOfTo, sizeOfCc, 0, email, attachments);
}
#ifdef SSLCLIENT_WRAPPER
#ifdef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION
// Initialize the SSL client library
// We input an EthernetClient, our trust anchors, and the analog pin
EMAIL_NETWORK_CLASS base_client;
SSLClient client(base_client, TAs, (size_t)TAs_NUM, ANALOG_PIN, 2);
#else
#error "You must put outside scope the client declaration if you want use SSLClient!"
#endif
#else
#ifdef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION
EMAIL_NETWORK_CLASS client;
#endif
#endif
EMailSender::Response EMailSender::send(const char* to[], byte sizeOfTo, byte sizeOfCc,byte sizeOfCCn, EMailMessage &email, Attachments attachments)
{
unsigned long loopTime1, loopTime2;
#ifdef SSLCLIENT_WRAPPER
DEBUG_PRINTLN(F("SSLClient active!"));
#else
#ifndef PUT_OUTSIDE_SCOPE_CLIENT_DECLARATION
EMAIL_NETWORK_CLASS client;
#endif
DEBUG_PRINT(F("Insecure client:"));
DEBUG_PRINTLN(this->isSecure);
#if (EMAIL_NETWORK_TYPE == NETWORK_ESP8266 || EMAIL_NETWORK_TYPE == NETWORK_ESP8266_242)
#ifndef ARDUINO_ESP8266_RELEASE_2_4_2
if (this->isSecure == false){
client.setInsecure();
bool mfln = client.probeMaxFragmentLength(this->smtp_server, this->smtp_port, 512);
DEBUG_PRINT("MFLN supported: ");
DEBUG_PRINTLN(mfln?"yes":"no");
if (mfln) {
client.setBufferSizes(512, 512);
}
}
#endif
#elif (EMAIL_NETWORK_TYPE == NETWORK_ESP32)
// String coreVersion = String(ESP.getSdkVersion());
// uint8_t firstdot = coreVersion.indexOf('.');
//
// DEBUG_PRINTLN(coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat());
// DEBUG_PRINTLN(coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat() >= 3.3f);
// if (coreVersion.substring(1, coreVersion.indexOf('.', firstdot+1)).toFloat() >= 3.3f) {
// client.setInsecure();
// }
#include <core_version.h>
#if ((!defined(ARDUINO_ESP32_RELEASE_1_0_4)) && (!defined(ARDUINO_ESP32_RELEASE_1_0_3)) && (!defined(ARDUINO_ESP32_RELEASE_1_0_2)))
client.setInsecure();
#endif
#endif
#endif
EMailSender::Response response;
DEBUG_PRINTLN(this->smtp_server);
DEBUG_PRINTLN(this->smtp_port);
if(!client.connect(this->smtp_server, this->smtp_port)) {
response.desc = F("Could not connect to mail server");
response.code = F("2");
response.status = false;
client.flush();
client.stop();
return response;
}
response = awaitSMTPResponse(client, "220", "Connection Error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
String commandHELO = "HELO";
if (this->useEHLO == true) {
commandHELO = "EHLO";
}
String helo = commandHELO + " "+/*String(publicIPDescriptor)*/ smtp_server /*+": "*/;
DEBUG_PRINTLN(helo);
client.println(helo);
response = awaitSMTPResponse(client, "250", "Identification error");
DEBUG_PRINTLN(response.status);
if (!response.status) {
client.flush();
client.stop();
return response;
}
loopTime1 = millis();
DEBUG_PRINTLN(loopTime1);
if (this->useEHLO == true) {
for (int i = 0; i<=20; i++) {
awaitSMTPResponse(client);
loopTime2 = millis();
DEBUG_PRINTLN(loopTime2);
if ((loopTime2 - loopTime1) > 2500) {
break;
} else {
loopTime1 = loopTime2;
}
}
}
DEBUG_PRINTLN("End of awaitSMTPResponse");
if (useAuth){
if (this->isSASLLogin == true){
int size = 1 + strlen(this->email_login)+ strlen(this->email_password)+2;
char * logPass = (char *) malloc(size);
// strcpy(logPass, " ");
// strcat(logPass, this->email_login);
// strcat(logPass, " ");
// strcat(logPass, this->email_password);
// String logPass;
int maincont = 0;
logPass[maincont++] = ' ';
logPass[maincont++] = (char) 0;
for (unsigned int i = 0;i<strlen(this->email_login);i++){
logPass[maincont++] = this->email_login[i];
}
logPass[maincont++] = (char) 0;
for (unsigned int i = 0;i<strlen(this->email_password);i++){
logPass[maincont++] = this->email_password[i];
}
// strcpy(logPass, "\0");
// strcat(logPass, this->email_login);
// strcat(logPass, "\0");
// strcat(logPass, this->email_password);
String auth = "AUTH PLAIN "+String(encode64_f(logPass, size));
// String auth = "AUTH PLAIN "+String(encode64(logPass));
DEBUG_PRINTLN(auth);
client.println(auth);
}else{
DEBUG_PRINTLN(F("AUTH LOGIN:"));
client.println(F("AUTH LOGIN"));
awaitSMTPResponse(client);
DEBUG_PRINTLN(encode64(this->email_login));
client.println(encode64(this->email_login));
awaitSMTPResponse(client);
DEBUG_PRINTLN(encode64(this->email_password));
client.println(encode64(this->email_password));
}
response = awaitSMTPResponse(client, "235", "SMTP AUTH error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
}
DEBUG_PRINT(F("MAIL FROM: <"));
DEBUG_PRINT(this->email_from);
DEBUG_PRINTLN(F(">"));
client.print(F("MAIL FROM: <"));
client.print(this->email_from);
client.println(F(">"));
awaitSMTPResponse(client);
// String rcpt = "RCPT TO: <" + String(to) + '>';
//
// DEBUG_PRINTLN(rcpt);
// client.println(rcpt);
int cont;
for (cont=0;cont<(sizeOfTo+sizeOfCc+sizeOfCCn);cont++){
DEBUG_PRINT(F("RCPT TO: <"));
DEBUG_PRINT(to[cont]);
DEBUG_PRINTLN(F(">"));
client.print(F("RCPT TO: <"));
client.print(to[cont]);
client.println(F(">"));
awaitSMTPResponse(client);
}
DEBUG_PRINTLN(F("DATA:"));
client.println(F("DATA"));
response = awaitSMTPResponse(client, "354", "SMTP DATA error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
// client.println("From: <" + String(this->email_from) + '>');
client.print(F("From: "));
if (this->name_from){
client.print(this->name_from);
}
client.print(F(" <"));
client.print(this->email_from);
client.println(F(">"));
// client.println("To: <" + String(to) + '>');
client.print(F("To: "));
for (cont=0;cont<sizeOfTo;cont++){
client.print(F("<"));
client.print(to[cont]);
client.print(">");
if (cont!=sizeOfTo-1){
client.print(",");
}
}
client.println();
if (sizeOfCc>0){
client.print(F("Cc: "));
for (;cont<sizeOfTo+sizeOfCc;cont++){
client.print(F("<"));
client.print(to[cont]);
client.print(">");
if (cont!=sizeOfCc-1){
client.print(",");
}
}
client.println();
}
if (sizeOfCCn>0){
client.print(F("CCn: "));
for (;cont<sizeOfTo+sizeOfCc+sizeOfCCn;cont++){
client.print(F("<"));
client.print(to[cont]);
client.print(">");
if (cont!=sizeOfCCn-1){
client.print(",");
}
}
client.println();
}
client.print(F("Subject: "));
client.println(email.subject);
// client.println(F("Mime-Version: 1.0"));
client.println(F("MIME-Version: 1.0"));
client.println(F("Content-Type: Multipart/mixed; boundary=frontier"));
client.println(F("--frontier"));
client.print(F("Content-Type: "));
client.print(email.mime);
client.println(F("; charset=\"UTF-8\""));
// client.println(F("Content-Type: text/html; charset=\"UTF-8\""));
client.println(F("Content-Transfer-Encoding: 7bit"));
client.println();
if (email.mime==F("text/html")){
// String body = "<!DOCTYPE html><html lang=\"en\">" + String(email.message) + "</html>";
client.print(F("<!DOCTYPE html><html lang=\"en\">"));
client.print(email.message);
client.println(F("</html>"));
// client.println(body);
}else{
client.println(email.message);
}
client.println();
#ifdef STORAGE_INTERNAL_ENABLED
bool spiffsActive = false;
#endif
#ifdef STORAGE_EXTERNAL_ENABLED
bool sdActive = false;
#endif
#if defined(ENABLE_ATTACHMENTS) && (defined(STORAGE_EXTERNAL_ENABLED) || defined(STORAGE_INTERNAL_ENABLED))
// if ((sizeof(attachs) / sizeof(attachs[0]))>0){
if (sizeof(attachments)>0 && attachments.number>0){
DEBUG_PRINT(F("Array: "));
// for (int i = 0; i<(sizeof(attachs) / sizeof(attachs[0])); i++){
for (int i = 0; i<attachments.number; i++){
uint8_t tBuf[64];
if (attachments.fileDescriptor[i].url.length()==0){
EMailSender::Response response;
response.code = F("400");
response.desc = "Error no filename specified for the file "+attachments.fileDescriptor[i].filename;
response.status = false;
client.flush();
client.stop();
return response;
}
if (attachments.fileDescriptor[i].mime.length()==0){
EMailSender::Response response;
response.code = F("400");
response.desc = "Error no mime type specified for the file "+attachments.fileDescriptor[i].url;
response.status = false;
client.flush();
client.stop();
return response;
}
if (attachments.fileDescriptor[i].filename.length()==0){
EMailSender::Response response;
response.code = F("400");
response.desc = "Error no filename specified for the file "+attachments.fileDescriptor[i].url;
response.status = false;
client.flush();
client.stop();
return response;
}
DEBUG_PRINTLN(attachments.fileDescriptor[i].filename);
DEBUG_PRINTLN(F("--frontier"));
client.println(F("--frontier"));
DEBUG_PRINTLN(F("Content-Type: "));
client.print(F("Content-Type: "));
DEBUG_PRINTLN(attachments.fileDescriptor[i].mime);
client.print(attachments.fileDescriptor[i].mime);
DEBUG_PRINTLN(F("; charset=\"UTF-8\""));
client.println(F("; charset=\"UTF-8\""));
if (attachments.fileDescriptor[i].encode64){
client.println(F("Content-Transfer-Encoding: base64"));
}
client.print(F("Content-Disposition: attachment; filename="));
client.print(attachments.fileDescriptor[i].filename);
client.println(F("\n"));
int clientCount = 0;
#ifdef STORAGE_INTERNAL_ENABLED
if (attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SPIFFS ||
attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_LITTLE_FS ||
attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SPIFM ||
attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_FFAT){
#ifdef OPEN_CLOSE_INTERNAL
if (!INTERNAL_STORAGE_CLASS.exists(attachments.fileDescriptor[i].url.c_str())){
#if (INTERNAL_STORAGE == STORAGE_SPIFM)
Adafruit_FlashTransport_SPI flashTransport(SPIFM_CS_PIN, SPI); // Set CS and SPI interface
Adafruit_SPIFlash flash(&flashTransport);
// Initialize flash library and check its chip ID.
if (!flash.begin()) {
EMailSender::Response response;
response.code = F("500");
response.desc = F("Error, failed to initialize flash chip!");
response.status = false;
client.flush();
client.stop();
return response;
} // close flash.begin()
if(!(INTERNAL_STORAGE_CLASS.begin(&flash))){
#else
if(!(INTERNAL_STORAGE_CLASS.begin())){
#endif
EMailSender::Response response;
response.code = F("500");
response.desc = F("Error on startup filesystem!");
response.status = false;
client.flush();
client.stop();
return response;
} // Close INTERNAL_STORAGE_CLASS.begin
spiffsActive = true;
DEBUG_PRINTLN("SPIFFS BEGIN, ACTIVE");
} // Close INTERNAL_STORAGE_CLASS.exists
#endif
EMAIL_FILE myFile = INTERNAL_STORAGE_CLASS.open(attachments.fileDescriptor[i].url, EMAIL_FILE_READ);
if(myFile) {
// DEBUG_PRINTLN(myFile.name());
if (attachments.fileDescriptor[i].encode64){
encode(&myFile, &client);
}else{
while(myFile.available()) {
clientCount = myFile.read(tBuf,64);
DEBUG_PRINTLN(clientCount);
client.write((byte*)tBuf,clientCount);
}
}
myFile.close();
client.println();
} // Else myfile
else {
EMailSender::Response response;
response.code = F("404");
response.desc = "Error opening attachments file "+attachments.fileDescriptor[i].url;
response.status = false;
client.flush();
client.stop();
return response;
} // Close myfile
} // Close storageType
#endif
#ifdef STORAGE_EXTERNAL_ENABLED
if (attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SD){
#ifdef OPEN_CLOSE_SD
DEBUG_PRINTLN(F("SD Check"));
if (!EXTERNAL_STORAGE_CLASS.exists(attachments.fileDescriptor[i].url.c_str())){
#if EXTERNAL_STORAGE == STORAGE_SD || EXTERNAL_STORAGE == STORAGE_SDFAT2
if(!EXTERNAL_STORAGE_CLASS.begin(SD_CS_PIN)){
response.code = F("500");
response.desc = F("Error on startup SD filesystem!");
response.status = false;
client.flush();
client.stop();
return response;
} // Close EXTERNAL_STORAGE_CLASS.begin
#elif EXTERNAL_STORAGE == STORAGE_SPIFM
Adafruit_FlashTransport_SPI flashTransport(SS, SPI); // Set CS and SPI interface
Adafruit_SPIFlash flash(&flashTransport);
if (!EXTERNAL_STORAGE_CLASS.begin(&flash)) {
response.code = F("500");
response.desc = F("Error on startup SDFAT2 filesystem!");
response.status = false;
client.flush();
client.stop();
return response;
}
#endif
sdActive = true;
} // Close EXTERNAL_STORAGE_CLASS.exists
#endif
DEBUG_PRINTLN(F("Open file: "));
EMAIL_FILE_EX myFile = EXTERNAL_STORAGE_CLASS.open(attachments.fileDescriptor[i].url.c_str());
if(myFile) {
myFile.seek(0);
DEBUG_PRINTLN(F("OK"));
if (attachments.fileDescriptor[i].encode64){
DEBUG_PRINTLN(F("BASE 64"));
encode(&myFile, &client);
}else{
DEBUG_PRINTLN(F("NORMAL"));
while(myFile.available()) {
clientCount = myFile.read(tBuf,64);
client.write((byte*)tBuf,clientCount);
}
}
myFile.close();
client.println();
} // Else myfile
else {
response.code = F("404");
response.desc = "Error opening attachments file "+attachments.fileDescriptor[i].url;
response.status = false;
client.flush();
client.stop();
return response;
} // Close myFile
} // Close storageType==EMAIL_STORAGE_TYPE_SD
#else
if (attachments.fileDescriptor[i].storageType==EMAIL_STORAGE_TYPE_SD){
response.code = F("500");
response.desc = F("EMAIL_STORAGE_TYPE_SD not enabled on EMailSenderKey.h");
response.status = false;
client.flush();
client.stop();
return response;
}
#endif
} // Close attachment cycle
client.println();
client.println(F("--frontier--"));
#ifdef STORAGE_EXTERNAL_ENABLED
#ifdef OPEN_CLOSE_SD
if (sdActive){
DEBUG_PRINTLN(F("SD end"));
#ifndef ARDUINO_ESP8266_RELEASE_2_4_2
EXTERNAL_STORAGE_CLASS.end();
#endif
DEBUG_PRINTLN(F("SD end 2"));
}
#endif
#endif
#ifdef STORAGE_INTERNAL_ENABLED
#ifdef OPEN_CLOSE_INTERNAL
#if INTERNAL_STORAGE != STORAGE_SPIFM
if (spiffsActive){
INTERNAL_STORAGE_CLASS.end();
DEBUG_PRINTLN(F("SPIFFS END"));
}
#endif
#endif
#endif
} // Close attachement enable
#endif
DEBUG_PRINTLN(F("Message end"));
client.println(F("."));
response = awaitSMTPResponse(client, "250", "Sending message error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
client.println(F("QUIT"));
response = awaitSMTPResponse(client, "221", "SMTP QUIT error");
if (!response.status) {
client.flush();
client.stop();
return response;
}
response.status = true;
response.code = F("0");
response.desc = F("Message sent!");
client.flush();
client.stop();
return response;
}
|
Thank you. I also had something similar in mind. |
I simplified it a bit: |
Thanks – I guess the await function had a max timeout field – that’s neater.
How long before these make it on the official Arduino libraries
From: BenSeventy9 ***@***.***>
Sent: July 2, 2022 12:03
To: xreef/EMailSender ***@***.***>
Cc: rsalasidis ***@***.***>; Mention ***@***.***>
Subject: Re: [xreef/EMailSender] Needs more than 40 seconds to send. Any ideas why? (Issue #26)
I simplified it a bit:
if (this->useEHLO == true) { for (int i = 0; i<=6; i++) { response = awaitSMTPResponse(client, "250", "EHLO error", 2500); if (!response.status) { DEBUG_PRINTLN(response.desc); break; } } }
—
Reply to this email directly, view it on GitHub<#26 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AK5VYZLNFVDQMUKYZ3W2RDDVSBR4PANCNFSM5ZMZRLZQ>.
You are receiving this because you were mentioned.Message ID: ***@***.******@***.***>>
|
Hi all, |
Hi, |
I think you made a little mistake. Should't it be like this? |
Azz.. yes, there is a copy-paste error @BenSeventy9 . |
I hope It's the last fix. |
Serial Monitor:
My code:
Credentials and mail replaced by "***"
The text was updated successfully, but these errors were encountered: