aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-02-17 17:07:23 +0000
committerVincent Richard <[email protected]>2013-02-17 17:07:23 +0000
commit0757efad0d0669766236eefbedad98ee8541a5f5 (patch)
treecd157a402a5f0c6d9bc3da37a33987981d708b0c
parentAlways throw std exceptions (eg. bad_alloc) and VMime time out exceptions. (diff)
downloadvmime-0757efad0d0669766236eefbedad98ee8541a5f5.tar.gz
vmime-0757efad0d0669766236eefbedad98ee8541a5f5.zip
Reset SMTP session state (using RSET command) if transport is being reused.
-rw-r--r--src/net/smtp/SMTPCommand.cpp7
-rw-r--r--src/net/smtp/SMTPTransport.cpp22
-rw-r--r--tests/net/smtp/SMTPCommandTest.cpp9
-rw-r--r--vmime/net/smtp/SMTPCommand.hpp1
-rw-r--r--vmime/net/smtp/SMTPTransport.hpp2
5 files changed, 40 insertions, 1 deletions
diff --git a/src/net/smtp/SMTPCommand.cpp b/src/net/smtp/SMTPCommand.cpp
index 13b1dc5d..f338e248 100644
--- a/src/net/smtp/SMTPCommand.cpp
+++ b/src/net/smtp/SMTPCommand.cpp
@@ -108,6 +108,13 @@ ref <SMTPCommand> SMTPCommand::RCPT(const mailbox& mbox)
// static
+ref <SMTPCommand> SMTPCommand::RSET()
+{
+ return createCommand("RSET");
+}
+
+
+// static
ref <SMTPCommand> SMTPCommand::DATA()
{
return createCommand("DATA");
diff --git a/src/net/smtp/SMTPTransport.cpp b/src/net/smtp/SMTPTransport.cpp
index 8a3362e2..f1fa76aa 100644
--- a/src/net/smtp/SMTPTransport.cpp
+++ b/src/net/smtp/SMTPTransport.cpp
@@ -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);
diff --git a/tests/net/smtp/SMTPCommandTest.cpp b/tests/net/smtp/SMTPCommandTest.cpp
index 93cdf7ae..0ff52741 100644
--- a/tests/net/smtp/SMTPCommandTest.cpp
+++ b/tests/net/smtp/SMTPCommandTest.cpp
@@ -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:<[email protected]>", 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();
diff --git a/vmime/net/smtp/SMTPCommand.hpp b/vmime/net/smtp/SMTPCommand.hpp
index ccf445e5..3a28445f 100644
--- a/vmime/net/smtp/SMTPCommand.hpp
+++ b/vmime/net/smtp/SMTPCommand.hpp
@@ -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();
diff --git a/vmime/net/smtp/SMTPTransport.hpp b/vmime/net/smtp/SMTPTransport.hpp
index 50885203..20f4bc52 100644
--- a/vmime/net/smtp/SMTPTransport.hpp
+++ b/vmime/net/smtp/SMTPTransport.hpp
@@ -105,6 +105,8 @@ private:
SMTPResponse::state m_responseState;
+ bool m_needReset;
+
// Service infos
static SMTPServiceInfos sm_infos;
};