diff --git a/examples/SMTP/Send_Text/Send_Text.ino b/examples/SMTP/Send_Text/Send_Text.ino index 12831e4..07acbc5 100644 --- a/examples/SMTP/Send_Text/Send_Text.ino +++ b/examples/SMTP/Send_Text/Send_Text.ino @@ -219,7 +219,7 @@ void setup() SMTP_Message message; /* Set the message headers */ - message.sender.name = F("ESP Mail"); + message.sender.name = F("Me (我)"); message.sender.email = AUTHOR_EMAIL; /** If author and sender are not identical @@ -234,16 +234,14 @@ void setup() // in form of `encoded-words` per RFC2047 // https://datatracker.ietf.org/doc/html/rfc2047 - String subject = "Test sending message (中文电子邮件)"; - String encoded_subject = "=?utf-8?B?"; - encoded_subject += MailClient.toBase64(subject); - encoded_subject += "?="; + String subject = "Test sending a message (メッセージの送信をテストする)"; + message.subject = subject; - message.subject = encoded_subject; + message.addRecipient(F("Someone (誰か)"), RECIPIENT_EMAIL); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - String textMsg = "This is simple plain text message with Chinese words (中文电子邮件) in subject and body"; + String textMsg = "This is simple plain text message which contains Chinese and Japanese words.\n"; + textMsg += "这是简单的纯文本消息,包含中文和日文单词\n"; + textMsg += "これは中国語と日本語を含む単純なプレーンテキストメッセージです\n"; message.text.content = textMsg; diff --git a/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino b/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino index 8d3b3ce..14bff10 100644 --- a/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino +++ b/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino @@ -181,7 +181,7 @@ void setup() /* Set the message headers */ message.sender.name = F("ESP Mail"); message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); + message.subject = F("Test sending a plain text message"); message.addRecipient(F("Someone"), RECIPIENT_EMAIL); /** The option to add soft line break to to the message for diff --git a/examples/SMTP/Set_Time/Set_Time.ino b/examples/SMTP/Set_Time/Set_Time.ino index 76643d7..bda2958 100644 --- a/examples/SMTP/Set_Time/Set_Time.ino +++ b/examples/SMTP/Set_Time/Set_Time.ino @@ -133,8 +133,8 @@ void setup() RTC.begin(); - // RTCTime startTime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE); - // RTC.setTime(startTime); + RTCTime startTime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE); + RTC.setTime(startTime); RTCTime currentTime; diff --git a/library.json b/library.json index d08d44f..92168dd 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Mail Client", - "version": "3.4.14", + "version": "3.4.15", "keywords": "communication, email, imap, smtp, esp32, esp8266, samd, arduino", "description": "Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. The library also supported other Arduino Devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient.", "repository": { diff --git a/library.properties b/library.properties index a2902a4..56b5ac4 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Mail Client -version=3.4.14 +version=3.4.15 author=Mobizt diff --git a/src/ESP_Mail_Client.cpp b/src/ESP_Mail_Client.cpp index 827b047..216328f 100644 --- a/src/ESP_Mail_Client.cpp +++ b/src/ESP_Mail_Client.cpp @@ -4,7 +4,7 @@ #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif @@ -798,7 +798,7 @@ void ESP_Mail_Client::appendHeaderField(MB_String &buf, const char *name, PGM_P appendString(buf, value, comma, newLine, type); } -void ESP_Mail_Client::appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine) +void ESP_Mail_Client::appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine, bool encode) { // Construct header field. if (header) @@ -807,7 +807,7 @@ void ESP_Mail_Client::appendAddressHeaderField(MB_String &buf, esp_mail_address_ if (type != esp_mail_rfc822_header_field_cc && type != esp_mail_rfc822_header_field_bcc && source.name.length() > 0) { - appendString(buf, source.name.c_str(), false, false, esp_mail_string_mark_type_double_quote); + appendString(buf, encode ? encodeBUTF8(source.name.c_str()).c_str() : source.name.c_str(), false, false, esp_mail_string_mark_type_double_quote); // Add white space after name for SMTP to fix iCloud Mail Service IMAP search compatibility issue #278 // This is not restricted by rfc2822. appendSpace(buf); @@ -976,6 +976,21 @@ MB_String ESP_Mail_Client::mGetBase64(MB_StringPtr str) return encodeBase64Str((uint8_t *)(data.c_str()), data.length()); } +MB_String ESP_Mail_Client::encodeBUTF8(const char *src) +{ + MB_String buff; + size_t len = strlen(src); + if (len > 4 && src[0] != '=' && src[1] != '?' && src[len - 1] != '=' && src[len - 2] != '?') + { + buff = "=?utf-8?B?"; + buff += toBase64(src); + buff += "?="; + } + else + buff = src; + return buff; +} + int ESP_Mail_Client::readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout) { int ret = -1; diff --git a/src/ESP_Mail_Client.h b/src/ESP_Mail_Client.h index 94703fa..d289c31 100644 --- a/src/ESP_Mail_Client.h +++ b/src/ESP_Mail_Client.h @@ -2,7 +2,7 @@ #define ESP_MAIL_CLIENT_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif @@ -1189,6 +1189,9 @@ class ESP_Mail_Client // Decode base64 encoded string MB_String mGetBase64(MB_StringPtr str); + + // RFC2047 encode word (UTF-8 only) + MB_String encodeBUTF8(const char* str); // Sub string char *subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos = 0, bool caseSensitive = true); @@ -1245,7 +1248,7 @@ class ESP_Mail_Client void appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); // Append SMTP address header field - void appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine); + void appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine, bool encode); // Append header field name to buffer void appendHeaderName(MB_String &buf, const char *name, bool clear = false, bool lowercase = false, bool space = true); diff --git a/src/ESP_Mail_Client_Version.h b/src/ESP_Mail_Client_Version.h index 9fed60c..2a78024 100644 --- a/src/ESP_Mail_Client_Version.h +++ b/src/ESP_Mail_Client_Version.h @@ -3,8 +3,8 @@ #ifndef ESP_MAIL_VERSION -#define ESP_MAIL_VERSION "3.4.14" -#define ESP_MAIL_VERSION_NUM 30414 +#define ESP_MAIL_VERSION "3.4.15" +#define ESP_MAIL_VERSION_NUM 30415 /* The inconsistent file version checking to prevent mixed versions compilation. */ #define VALID_VERSION_CHECK(ver) (ver == ESP_MAIL_VERSION_NUM) diff --git a/src/ESP_Mail_Const.h b/src/ESP_Mail_Const.h index ee75d21..c7237f0 100644 --- a/src/ESP_Mail_Const.h +++ b/src/ESP_Mail_Const.h @@ -6,7 +6,7 @@ #define ESP_MAIL_CONST_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/ESP_Mail_Error.h b/src/ESP_Mail_Error.h index 997c455..8cc8eac 100644 --- a/src/ESP_Mail_Error.h +++ b/src/ESP_Mail_Error.h @@ -7,7 +7,7 @@ #define ESP_MAIL_ERROR_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/ESP_Mail_FS.h b/src/ESP_Mail_FS.h index 1ff6d19..159eefe 100644 --- a/src/ESP_Mail_FS.h +++ b/src/ESP_Mail_FS.h @@ -6,7 +6,7 @@ #define ESP_MAIL_CONFIG_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/ESP_Mail_IMAP.h b/src/ESP_Mail_IMAP.h index ea60197..eb27fd3 100644 --- a/src/ESP_Mail_IMAP.h +++ b/src/ESP_Mail_IMAP.h @@ -3,7 +3,7 @@ #define ESP_MAIL_IMAP_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/ESP_Mail_SMTP.h b/src/ESP_Mail_SMTP.h index 88e7df3..1759927 100644 --- a/src/ESP_Mail_SMTP.h +++ b/src/ESP_Mail_SMTP.h @@ -3,7 +3,7 @@ #define ESP_MAIL_SMTP_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif @@ -557,12 +557,12 @@ bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool clo if (msg->sender.email.length() > 0 && msg->author.email.length() > 0 && strcmp(msg->sender.email.c_str(), msg->author.email.c_str()) != 0) { - appendAddressHeaderField(buf2, msg->author, esp_mail_rfc822_header_field_from, true, false, true); - appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); + appendAddressHeaderField(buf2, msg->author, esp_mail_rfc822_header_field_from, true, false, true, true); + appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true, true); } // If author and transmitter (agent) are identical, send only 'From' header else if (msg->sender.email.length() > 0) - appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_from, true, false, true); + appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_from, true, false, true, true); if (!imap && smtp) { @@ -602,7 +602,7 @@ bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool clo for (uint8_t i = 0; i < msg->_rcp.size(); i++) { - appendAddressHeaderField(buf2, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); + appendAddressHeaderField(buf2, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1, true); if (!imap && smtp) { // only address @@ -652,7 +652,7 @@ bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool clo // Construct 'Cc' header field. for (uint8_t i = 0; i < msg->_cc.size(); i++) { - appendAddressHeaderField(buf2, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); + appendAddressHeaderField(buf2, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1, true); if (!imap) { // only address @@ -718,7 +718,7 @@ bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool clo return false; MB_String s; - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_subject].text, MailClient.encodeBUTF8(msg->subject.c_str()).c_str(), false, true); if (msg->timestamp.tag.length() && msg->timestamp.format.length()) s.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); @@ -805,10 +805,10 @@ bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool clo appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); if (msg->comments.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_comments].text, MailClient.encodeBUTF8(msg->comments.c_str()).c_str(), false, true); if (msg->keywords.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, MailClient.encodeBUTF8(msg->keywords.c_str()).c_str(), false, true); if (msg->messageID.length() > 0) appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); @@ -998,11 +998,11 @@ void ESP_Mail_Client::getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, // Construct 'From' header field. if (msg->from.email.length() > 0) - appendAddressHeaderField(buf, msg->from, esp_mail_rfc822_header_field_from, true, false, true); + appendAddressHeaderField(buf, msg->from, esp_mail_rfc822_header_field_from, true, false, true, true); // Construct 'Sender' header field. if (msg->sender.email.length() > 0) - appendAddressHeaderField(buf, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); + appendAddressHeaderField(buf, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true, true); if (msg->response.reply_to.length() > 0) appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); @@ -1012,22 +1012,22 @@ void ESP_Mail_Client::getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, // Construct 'To' header field. for (uint8_t i = 0; i < msg->_rcp.size(); i++) - appendAddressHeaderField(buf, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); + appendAddressHeaderField(buf, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1, true); for (uint8_t i = 0; i < msg->_cc.size(); i++) - appendAddressHeaderField(buf, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); + appendAddressHeaderField(buf, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1, true); for (uint8_t i = 0; i < msg->_bcc.size(); i++) - appendAddressHeaderField(buf, msg->_bcc[i], esp_mail_rfc822_header_field_bcc, i == 0, i > 0, i == msg->_bcc.size() - 1); + appendAddressHeaderField(buf, msg->_bcc[i], esp_mail_rfc822_header_field_bcc, i == 0, i > 0, i == msg->_bcc.size() - 1, true); if (msg->subject.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_subject].text, MailClient.encodeBUTF8(msg->subject.c_str()).c_str(), false, true); if (msg->keywords.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, MailClient.encodeBUTF8(msg->keywords.c_str()).c_str(), false, true); if (msg->comments.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_comments].text, MailClient.encodeBUTF8(msg->comments.c_str()).c_str(), false, true); if (msg->in_reply_to.length() > 0) appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); diff --git a/src/ESP_Mail_TCPClient.h b/src/ESP_Mail_TCPClient.h index d6c2308..e13c415 100644 --- a/src/ESP_Mail_TCPClient.h +++ b/src/ESP_Mail_TCPClient.h @@ -1,8 +1,8 @@ /** * - * The Network Upgradable Arduino Secure TCP Client Class, ESP_Mail_TCPClient.h v1.0.4 + * The Network Upgradable Arduino Secure TCP Client Class, ESP_Mail_TCPClient.h v3.4.15 * - * Created September 14, 2023 + * Created November 15, 2023 * * The MIT License (MIT) * Copyright (c) 2023 K. Suwatchai (Mobizt) @@ -30,7 +30,7 @@ #define ESP_MAIL_TCPCLIENT_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/extras/MB_String.h b/src/extras/MB_String.h index 775ade4..d0601cf 100644 --- a/src/extras/MB_String.h +++ b/src/extras/MB_String.h @@ -1,11 +1,15 @@ /** - * Mobizt's SRAM/PSRAM supported String, version 1.2.9 + * Mobizt's SRAM/PSRAM supported String, version 1.2.10 * - * Created December 3, 2022 + * Created November 15, 2023 * * Changes Log * + * + * v1.2.10 + * - add support Arduino UNO WiFi R4 + * * v1.2.9 * - substring optimization * @@ -900,7 +904,7 @@ class MB_String s = boolStr(value); else if (is_num_neg_int::value) { -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_UNOWIFIR4) s = int32Str(value); #else s = int64Str(value); @@ -908,7 +912,7 @@ class MB_String } else if (is_num_pos_int::value) { -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_UNOWIFIR4) s = uint32Str(value); #else s = uint64Str(value); @@ -1475,7 +1479,7 @@ class MB_String static const size_t npos = -1; private: -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_UNOWIFIR4) char *int32Str(signed long value) { diff --git a/src/extras/MB_Time.h b/src/extras/MB_Time.h index 3a3996a..d606388 100644 --- a/src/extras/MB_Time.h +++ b/src/extras/MB_Time.h @@ -2,7 +2,7 @@ #define MB_Time_H #include "./ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/extras/Networks.h b/src/extras/Networks.h index ea4a987..3b0f329 100644 --- a/src/extras/Networks.h +++ b/src/extras/Networks.h @@ -4,7 +4,7 @@ #include "./ESP_Mail_FS.h" #include "./ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/extras/RFC2047.cpp b/src/extras/RFC2047.cpp index 9c5f424..36e5c74 100644 --- a/src/extras/RFC2047.cpp +++ b/src/extras/RFC2047.cpp @@ -2,7 +2,7 @@ #define RFC2047_CPP #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif diff --git a/src/extras/RFC2047.h b/src/extras/RFC2047.h index 8aaa561..86f5f33 100644 --- a/src/extras/RFC2047.h +++ b/src/extras/RFC2047.h @@ -4,7 +4,7 @@ #define RFC2047_H #include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30414) +#if !VALID_VERSION_CHECK(30415) #error "Mixed versions compilation." #endif