Added support for SMTPUTF8 extension (RFC-6531).

This commit is contained in:
Vincent Richard 2013-06-12 21:19:36 +02:00
parent f2211877a9
commit 93c8d3a071
6 changed files with 91 additions and 13 deletions

View File

@ -525,4 +525,15 @@ const string emailAddress::toString() const
} }
const text emailAddress::toText() const
{
text txt;
txt.appendWord(vmime::create <vmime::word>(m_localName));
txt.appendWord(vmime::create <vmime::word>("@", vmime::charsets::US_ASCII));
txt.appendWord(vmime::create <vmime::word>(m_domainName));
return txt;
}
} // vmime } // vmime

View File

@ -87,30 +87,47 @@ ref <SMTPCommand> SMTPCommand::STARTTLS()
// static // static
ref <SMTPCommand> SMTPCommand::MAIL(const mailbox& mbox) ref <SMTPCommand> SMTPCommand::MAIL(const mailbox& mbox, const bool utf8)
{ {
std::ostringstream cmd; std::ostringstream cmd;
cmd.imbue(std::locale::classic()); cmd.imbue(std::locale::classic());
cmd << "MAIL FROM:<"; cmd << "MAIL FROM:<";
vmime::utility::outputStreamAdapter cmd2(cmd); if (utf8)
mbox.getEmail().generate(cmd2); {
cmd << mbox.getEmail().toText().getConvertedText(vmime::charsets::UTF_8);
}
else
{
vmime::utility::outputStreamAdapter cmd2(cmd);
mbox.getEmail().generate(cmd2);
}
cmd << ">"; cmd << ">";
if (utf8)
cmd << " SMTPUTF8";
return createCommand(cmd.str()); return createCommand(cmd.str());
} }
// static // static
ref <SMTPCommand> SMTPCommand::RCPT(const mailbox& mbox) ref <SMTPCommand> SMTPCommand::RCPT(const mailbox& mbox, const bool utf8)
{ {
std::ostringstream cmd; std::ostringstream cmd;
cmd.imbue(std::locale::classic()); cmd.imbue(std::locale::classic());
cmd << "RCPT TO:<"; cmd << "RCPT TO:<";
vmime::utility::outputStreamAdapter cmd2(cmd); if (utf8)
mbox.getEmail().generate(cmd2); {
cmd << mbox.getEmail().toText().getConvertedText(vmime::charsets::UTF_8);
}
else
{
vmime::utility::outputStreamAdapter cmd2(cmd);
mbox.getEmail().generate(cmd2);
}
cmd << ">"; cmd << ">";

View File

@ -587,10 +587,13 @@ void SMTPTransport::send
commands->addCommand(SMTPCommand::RSET()); commands->addCommand(SMTPCommand::RSET());
// Emit the "MAIL" command // Emit the "MAIL" command
const bool hasSMTPUTF8 =
m_extensions.find("SMTPUTF8") != m_extensions.end();
if (!sender.isEmpty()) if (!sender.isEmpty())
commands->addCommand(SMTPCommand::MAIL(sender)); commands->addCommand(SMTPCommand::MAIL(sender, hasSMTPUTF8));
else else
commands->addCommand(SMTPCommand::MAIL(expeditor)); commands->addCommand(SMTPCommand::MAIL(expeditor, hasSMTPUTF8));
// Now, we will need to reset next time // Now, we will need to reset next time
m_needReset = true; m_needReset = true;
@ -599,7 +602,7 @@ void SMTPTransport::send
for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i)
{ {
const mailbox& mbox = *recipients.getMailboxAt(i); const mailbox& mbox = *recipients.getMailboxAt(i);
commands->addCommand(SMTPCommand::RCPT(mbox)); commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8));
} }
// Prepare sending of message data // Prepare sending of message data

View File

@ -39,7 +39,11 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest)
VMIME_TEST(testAUTH) VMIME_TEST(testAUTH)
VMIME_TEST(testSTARTTLS) VMIME_TEST(testSTARTTLS)
VMIME_TEST(testMAIL) VMIME_TEST(testMAIL)
VMIME_TEST(testMAIL_Encoded)
VMIME_TEST(testMAIL_UTF8)
VMIME_TEST(testRCPT) VMIME_TEST(testRCPT)
VMIME_TEST(testRCPT_Encoded)
VMIME_TEST(testRCPT_UTF8)
VMIME_TEST(testRSET) VMIME_TEST(testRSET)
VMIME_TEST(testDATA) VMIME_TEST(testDATA)
VMIME_TEST(testNOOP) VMIME_TEST(testNOOP)
@ -98,20 +102,56 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest)
void testMAIL() void testMAIL()
{ {
vmime::ref <SMTPCommand> cmd = SMTPCommand::MAIL(vmime::mailbox("me@vmime.org")); vmime::ref <SMTPCommand> cmd = SMTPCommand::MAIL(vmime::mailbox("me@vmime.org"), false);
VASSERT_NOT_NULL("Not null", cmd); VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "MAIL FROM:<me@vmime.org>", cmd->getText()); VASSERT_EQ("Text", "MAIL FROM:<me@vmime.org>", cmd->getText());
} }
void testMAIL_Encoded()
{
vmime::ref <SMTPCommand> cmd = SMTPCommand::MAIL
(vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false);
VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "MAIL FROM:<mailtest@xn--r8jz45g.xn--zckzah>", cmd->getText());
}
void testMAIL_UTF8()
{
vmime::ref <SMTPCommand> cmd = SMTPCommand::MAIL
(vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true);
VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "MAIL FROM:<mailtest@例え.テスト> SMTPUTF8", cmd->getText());
}
void testRCPT() void testRCPT()
{ {
vmime::ref <SMTPCommand> cmd = SMTPCommand::RCPT(vmime::mailbox("someone@vmime.org")); vmime::ref <SMTPCommand> cmd = SMTPCommand::RCPT(vmime::mailbox("someone@vmime.org"), false);
VASSERT_NOT_NULL("Not null", cmd); VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "RCPT TO:<someone@vmime.org>", cmd->getText()); VASSERT_EQ("Text", "RCPT TO:<someone@vmime.org>", cmd->getText());
} }
void testRCPT_Encoded()
{
vmime::ref <SMTPCommand> cmd = SMTPCommand::RCPT
(vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false);
VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "RCPT TO:<mailtest@xn--r8jz45g.xn--zckzah>", cmd->getText());
}
void testRCPT_UTF8()
{
vmime::ref <SMTPCommand> cmd = SMTPCommand::RCPT
(vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true);
VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "RCPT TO:<mailtest@例え.テスト>", cmd->getText());
}
void testRSET() void testRSET()
{ {
vmime::ref <SMTPCommand> cmd = SMTPCommand::RSET(); vmime::ref <SMTPCommand> cmd = SMTPCommand::RSET();

View File

@ -85,6 +85,13 @@ public:
*/ */
const string toString() const; const string toString() const;
/** Returns the email address as multibyte text, by joining components.
* (ie. the local name, followed by a @ then the domain name.)
*
* @return email address as multibyte text
*/
const text toText() const;
// Comparison // Comparison
bool operator==(const class emailAddress& eml) const; bool operator==(const class emailAddress& eml) const;
bool operator!=(const class emailAddress& eml) const; bool operator!=(const class emailAddress& eml) const;

View File

@ -63,8 +63,8 @@ public:
static ref <SMTPCommand> EHLO(const string& hostname); static ref <SMTPCommand> EHLO(const string& hostname);
static ref <SMTPCommand> AUTH(const string& mechName); static ref <SMTPCommand> AUTH(const string& mechName);
static ref <SMTPCommand> STARTTLS(); static ref <SMTPCommand> STARTTLS();
static ref <SMTPCommand> MAIL(const mailbox& mbox); static ref <SMTPCommand> MAIL(const mailbox& mbox, const bool utf8);
static ref <SMTPCommand> RCPT(const mailbox& mbox); static ref <SMTPCommand> RCPT(const mailbox& mbox, const bool utf8);
static ref <SMTPCommand> RSET(); static ref <SMTPCommand> RSET();
static ref <SMTPCommand> DATA(); static ref <SMTPCommand> DATA();
static ref <SMTPCommand> NOOP(); static ref <SMTPCommand> NOOP();