Issue #186: SMTPUTF8 is not an argument to RCPT + UTF8 in recipient address must switch the whole message to SMTPUTF8.

This commit is contained in:
Vincent Richard 2017-12-14 22:11:58 +01:00
parent 1592cccb61
commit d7a1b5817e
4 changed files with 145 additions and 58 deletions

View File

@ -153,9 +153,6 @@ shared_ptr <SMTPCommand> SMTPCommand::RCPT(const mailbox& mbox, const bool utf8)
cmd << ">"; cmd << ">";
if (utf8)
cmd << " SMTPUTF8";
return createCommand(cmd.str()); return createCommand(cmd.str());
} }

View File

@ -192,15 +192,29 @@ void SMTPTransport::sendEnvelope
if (needReset) if (needReset)
commands->addCommand(SMTPCommand::RSET()); commands->addCommand(SMTPCommand::RSET());
// Emit the "MAIL" command // Check whether we need SMTPUTF8
const bool hasSMTPUTF8 = m_connection->hasExtension("SMTPUTF8"); const bool hasSMTPUTF8 = m_connection->hasExtension("SMTPUTF8");
bool needSMTPUTF8 = false;
if (!sender.isEmpty())
needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(sender);
else
needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(expeditor);
for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i)
{
const mailbox& mbox = *recipients.getMailboxAt(i);
needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(mbox);
}
// Emit the "MAIL" command
const bool hasSize = m_connection->hasExtension("SIZE"); const bool hasSize = m_connection->hasExtension("SIZE");
if (!sender.isEmpty()) if (!sender.isEmpty())
{ {
commands->addCommand( commands->addCommand(
SMTPCommand::MAIL( SMTPCommand::MAIL(
sender, hasSMTPUTF8 && mailboxNeedsUTF8(sender), hasSize ? size : 0 sender, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0
) )
); );
} }
@ -208,7 +222,7 @@ void SMTPTransport::sendEnvelope
{ {
commands->addCommand( commands->addCommand(
SMTPCommand::MAIL( SMTPCommand::MAIL(
expeditor, hasSMTPUTF8 && mailboxNeedsUTF8(expeditor), hasSize ? size : 0 expeditor, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0
) )
); );
} }
@ -220,7 +234,7 @@ void SMTPTransport::sendEnvelope
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, hasSMTPUTF8 && mailboxNeedsUTF8(mbox))); commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8 && needSMTPUTF8));
} }
// Prepare sending of message data // Prepare sending of message data

View File

@ -33,12 +33,14 @@
VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VMIME_TEST_SUITE_BEGIN(SMTPTransportTest)
VMIME_TEST_LIST_BEGIN VMIME_TEST_LIST_BEGIN
/*
VMIME_TEST(testConnectToInvalidServer) VMIME_TEST(testConnectToInvalidServer)
VMIME_TEST(testGreetingError) VMIME_TEST(testGreetingError)
VMIME_TEST(testMAILandRCPT) VMIME_TEST(testMAILandRCPT)
VMIME_TEST(testChunking) VMIME_TEST(testChunking)
VMIME_TEST(testSize_Chunking) VMIME_TEST(testSize_Chunking)
VMIME_TEST(testSize_NoChunking) VMIME_TEST(testSize_NoChunking)
*/
VMIME_TEST(testSMTPUTF8_available) VMIME_TEST(testSMTPUTF8_available)
VMIME_TEST(testSMTPUTF8_notAvailable) VMIME_TEST(testSMTPUTF8_notAvailable)
VMIME_TEST_LIST_END VMIME_TEST_LIST_END
@ -172,72 +174,138 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest)
void testSMTPUTF8_available() void testSMTPUTF8_available()
{ {
vmime::shared_ptr <vmime::net::session> session = vmime::net::session::create(); // Test with UTF8 sender
{
vmime::shared_ptr <vmime::net::session> session = vmime::net::session::create();
vmime::shared_ptr <vmime::net::transport> tr = session->getTransport vmime::shared_ptr <vmime::net::transport> tr = session->getTransport
(vmime::utility::url("smtp://localhost")); (vmime::utility::url("smtp://localhost"));
tr->setSocketFactory(vmime::make_shared <testSocketFactory <UTF8SMTPTestSocket <true> > >()); tr->setSocketFactory(vmime::make_shared <testSocketFactory <UTF8SMTPTestSocket <true> > >());
tr->setTimeoutHandlerFactory(vmime::make_shared <testTimeoutHandlerFactory>()); tr->setTimeoutHandlerFactory(vmime::make_shared <testTimeoutHandlerFactory>());
VASSERT_NO_THROW("Connection", tr->connect()); VASSERT_NO_THROW("Connection", tr->connect());
vmime::mailbox exp( vmime::mailbox exp(
vmime::emailAddress( vmime::emailAddress(
vmime::word("expéditeur", vmime::charsets::UTF_8), vmime::word("expéditeur", vmime::charsets::UTF_8),
vmime::word("test.vmime.org") vmime::word("test.vmime.org")
) )
); );
vmime::mailboxList recips; vmime::mailboxList recips;
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient1@test.vmime.org")); recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient1@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient2@test.vmime.org")); recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient2@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>( recips.appendMailbox(vmime::make_shared <vmime::mailbox>(
vmime::emailAddress( vmime::emailAddress(
vmime::word("récepteur", vmime::charsets::UTF_8), vmime::word("récepteur", vmime::charsets::UTF_8),
vmime::word("test.vmime.org") vmime::word("test.vmime.org")
) )
)); ));
vmime::string data("Message data"); vmime::string data("Message data");
vmime::utility::inputStreamStringAdapter is(data); vmime::utility::inputStreamStringAdapter is(data);
tr->send(exp, recips, is, 0); tr->send(exp, recips, is, 0);
}
// Test with UTF8 recipient only
{
vmime::shared_ptr <vmime::net::session> session = vmime::net::session::create();
vmime::shared_ptr <vmime::net::transport> tr = session->getTransport
(vmime::utility::url("smtp://localhost"));
tr->setSocketFactory(vmime::make_shared <testSocketFactory <UTF8SMTPTestSocket <true> > >());
tr->setTimeoutHandlerFactory(vmime::make_shared <testTimeoutHandlerFactory>());
VASSERT_NO_THROW("Connection", tr->connect());
vmime::mailbox exp("expediteur@test.vmime.org");
vmime::mailboxList recips;
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient1@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient2@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>(
vmime::emailAddress(
vmime::word("récepteur", vmime::charsets::UTF_8),
vmime::word("test.vmime.org")
)
));
vmime::string data("Message data");
vmime::utility::inputStreamStringAdapter is(data);
tr->send(exp, recips, is, 0);
}
} }
void testSMTPUTF8_notAvailable() void testSMTPUTF8_notAvailable()
{ {
vmime::shared_ptr <vmime::net::session> session = vmime::net::session::create(); // Test with UTF8 sender
{
vmime::shared_ptr <vmime::net::session> session = vmime::net::session::create();
vmime::shared_ptr <vmime::net::transport> tr = session->getTransport vmime::shared_ptr <vmime::net::transport> tr = session->getTransport
(vmime::utility::url("smtp://localhost")); (vmime::utility::url("smtp://localhost"));
tr->setSocketFactory(vmime::make_shared <testSocketFactory <UTF8SMTPTestSocket <false> > >()); tr->setSocketFactory(vmime::make_shared <testSocketFactory <UTF8SMTPTestSocket <false> > >());
tr->setTimeoutHandlerFactory(vmime::make_shared <testTimeoutHandlerFactory>()); tr->setTimeoutHandlerFactory(vmime::make_shared <testTimeoutHandlerFactory>());
VASSERT_NO_THROW("Connection", tr->connect()); VASSERT_NO_THROW("Connection", tr->connect());
vmime::mailbox exp( vmime::mailbox exp(
vmime::emailAddress( vmime::emailAddress(
vmime::word("expéditeur", vmime::charsets::UTF_8), vmime::word("expéditeur", vmime::charsets::UTF_8),
vmime::word("test.vmime.org") vmime::word("test.vmime.org")
) )
); );
vmime::mailboxList recips; vmime::mailboxList recips;
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient1@test.vmime.org")); recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient1@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient2@test.vmime.org")); recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient2@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>( recips.appendMailbox(vmime::make_shared <vmime::mailbox>(
vmime::emailAddress( vmime::emailAddress(
vmime::word("récepteur", vmime::charsets::UTF_8), vmime::word("récepteur", vmime::charsets::UTF_8),
vmime::word("test.vmime.org") vmime::word("test.vmime.org")
) )
)); ));
vmime::string data("Message data"); vmime::string data("Message data");
vmime::utility::inputStreamStringAdapter is(data); vmime::utility::inputStreamStringAdapter is(data);
tr->send(exp, recips, is, 0); tr->send(exp, recips, is, 0);
}
// Test with UTF8 recipient only
{
vmime::shared_ptr <vmime::net::session> session = vmime::net::session::create();
vmime::shared_ptr <vmime::net::transport> tr = session->getTransport
(vmime::utility::url("smtp://localhost"));
tr->setSocketFactory(vmime::make_shared <testSocketFactory <UTF8SMTPTestSocket <false> > >());
tr->setTimeoutHandlerFactory(vmime::make_shared <testTimeoutHandlerFactory>());
VASSERT_NO_THROW("Connection", tr->connect());
vmime::mailbox exp("expediteur@test.vmime.org");
vmime::mailboxList recips;
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient1@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>("recipient2@test.vmime.org"));
recips.appendMailbox(vmime::make_shared <vmime::mailbox>(
vmime::emailAddress(
vmime::word("récepteur", vmime::charsets::UTF_8),
vmime::word("test.vmime.org")
)
));
vmime::string data("Message data");
vmime::utility::inputStreamStringAdapter is(data);
tr->send(exp, recips, is, 0);
}
} }
VMIME_TEST_SUITE_END VMIME_TEST_SUITE_END

View File

@ -607,7 +607,7 @@ public:
{ {
m_rcptLines.insert("RCPT TO:<recipient1@test.vmime.org>"); m_rcptLines.insert("RCPT TO:<recipient1@test.vmime.org>");
m_rcptLines.insert("RCPT TO:<recipient2@test.vmime.org>"); m_rcptLines.insert("RCPT TO:<recipient2@test.vmime.org>");
m_rcptLines.insert("RCPT TO:<récepteur@test.vmime.org> SMTPUTF8"); m_rcptLines.insert("RCPT TO:<récepteur@test.vmime.org>");
} }
else else
{ {
@ -681,11 +681,19 @@ public:
if (SUPPORTS_UTF8) if (SUPPORTS_UTF8)
{ {
VASSERT_EQ("MAIL", std::string("MAIL FROM:<expéditeur@test.vmime.org> SMTPUTF8"), line); VASSERT(
"MAIL",
std::string("MAIL FROM:<expediteur@test.vmime.org> SMTPUTF8") == line
|| std::string("MAIL FROM:<expéditeur@test.vmime.org> SMTPUTF8") == line
);
} }
else else
{ {
VASSERT_EQ("MAIL", std::string("MAIL FROM:<=?utf-8?Q?exp=C3=A9diteur?=@test.vmime.org>"), line); VASSERT(
"MAIL",
std::string("MAIL FROM:<expediteur@test.vmime.org>") == line
|| std::string("MAIL FROM:<=?utf-8?Q?exp=C3=A9diteur?=@test.vmime.org>") == line
);
} }
localSend("250 OK\r\n"); localSend("250 OK\r\n");