Reset SMTP session state (using RSET command) if transport is being reused.

This commit is contained in:
Vincent Richard 2013-02-17 18:07:23 +01:00
parent 0af0373cb6
commit 0757efad0d
5 changed files with 40 additions and 1 deletions

View File

@ -107,6 +107,13 @@ ref <SMTPCommand> SMTPCommand::RCPT(const mailbox& mbox)
}
// static
ref <SMTPCommand> SMTPCommand::RSET()
{
return createCommand("RSET");
}
// static
ref <SMTPCommand> SMTPCommand::DATA()
{

View File

@ -70,7 +70,7 @@ namespace smtp {
SMTPTransport::SMTPTransport(ref <session> sess, ref <security::authenticator> auth, const bool secured)
: transport(sess, getInfosInstance(), auth), m_socket(NULL),
m_authentified(false), m_extendedSMTP(false), m_timeoutHandler(NULL),
m_isSMTPS(secured), m_secured(false)
m_isSMTPS(secured), m_secured(false), m_needReset(false)
{
}
@ -574,15 +574,23 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
throw exceptions::no_expeditor();
const bool needReset = m_needReset;
const bool hasPipelining =
m_extensions.find("PIPELINING") != m_extensions.end();
ref <SMTPResponse> resp;
ref <SMTPCommandSet> commands = SMTPCommandSet::create(hasPipelining);
// Emit a "RSET" command if we previously sent a message on this connection
if (needReset)
commands->addCommand(SMTPCommand::RSET());
// Emit the "MAIL" command
commands->addCommand(SMTPCommand::MAIL(expeditor));
// Now, we will need to reset next time
m_needReset = true;
// Emit a "RCPT TO" command for each recipient
for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i)
{
@ -593,6 +601,18 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
// Prepare sending of message data
commands->addCommand(SMTPCommand::DATA());
// Read response for "RSET" command
if (needReset)
{
commands->writeToSocket(m_socket);
if ((resp = readResponse())->getCode() != 250)
{
internalDisconnect();
throw exceptions::command_error(commands->getLastCommandSent()->getText(), resp->getText());
}
}
// Read response for "MAIL" command
commands->writeToSocket(m_socket);

View File

@ -44,6 +44,7 @@ VMIME_TEST_SUITE_BEGIN
VMIME_TEST(testSTARTTLS)
VMIME_TEST(testMAIL)
VMIME_TEST(testRCPT)
VMIME_TEST(testRSET)
VMIME_TEST(testDATA)
VMIME_TEST(testNOOP)
VMIME_TEST(testQUIT)
@ -115,6 +116,14 @@ VMIME_TEST_SUITE_BEGIN
VASSERT_EQ("Text", "RCPT TO:<someone@vmime.org>", cmd->getText());
}
void testRSET()
{
vmime::ref <SMTPCommand> cmd = SMTPCommand::RSET();
VASSERT_NOT_NULL("Not null", cmd);
VASSERT_EQ("Text", "RSET", cmd->getText());
}
void testDATA()
{
vmime::ref <SMTPCommand> cmd = SMTPCommand::DATA();

View File

@ -65,6 +65,7 @@ public:
static ref <SMTPCommand> STARTTLS();
static ref <SMTPCommand> MAIL(const mailbox& mbox);
static ref <SMTPCommand> RCPT(const mailbox& mbox);
static ref <SMTPCommand> RSET();
static ref <SMTPCommand> DATA();
static ref <SMTPCommand> NOOP();
static ref <SMTPCommand> QUIT();

View File

@ -105,6 +105,8 @@ private:
SMTPResponse::state m_responseState;
bool m_needReset;
// Service infos
static SMTPServiceInfos sm_infos;
};