aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/smtp/SMTPTransport.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-06-20 09:02:39 +0000
committerVincent Richard <[email protected]>2013-06-20 09:02:39 +0000
commiteee80fc81e007baacbce80afe55e69a52bcfd1f6 (patch)
tree4ed1aeecac70ef7ab614f2956e306bbc427fe837 /src/net/smtp/SMTPTransport.cpp
parentMoved SMTP connection-related things to SMTPConnection object. (diff)
downloadvmime-eee80fc81e007baacbce80afe55e69a52bcfd1f6.tar.gz
vmime-eee80fc81e007baacbce80afe55e69a52bcfd1f6.zip
Added support for CHUNKING SMTP extension (RFC-3030). More robust unit tests for SMTP.
Diffstat (limited to 'src/net/smtp/SMTPTransport.cpp')
-rw-r--r--src/net/smtp/SMTPTransport.cpp72
1 files changed, 53 insertions, 19 deletions
diff --git a/src/net/smtp/SMTPTransport.cpp b/src/net/smtp/SMTPTransport.cpp
index 9e00ac4d..fb951bad 100644
--- a/src/net/smtp/SMTPTransport.cpp
+++ b/src/net/smtp/SMTPTransport.cpp
@@ -31,6 +31,7 @@
#include "vmime/net/smtp/SMTPResponse.hpp"
#include "vmime/net/smtp/SMTPCommand.hpp"
#include "vmime/net/smtp/SMTPCommandSet.hpp"
+#include "vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp"
#include "vmime/exception.hpp"
#include "vmime/mailboxList.hpp"
@@ -155,14 +156,10 @@ void SMTPTransport::noop()
}
-void SMTPTransport::send
+void SMTPTransport::sendEnvelope
(const mailbox& expeditor, const mailboxList& recipients,
- utility::inputStream& is, const utility::stream::size_type size,
- utility::progressListener* progress, const mailbox& sender)
+ const mailbox& sender, bool sendDATACommand)
{
- if (!isConnected())
- throw exceptions::not_connected();
-
// If no recipient/expeditor was found, throw an exception
if (recipients.isEmpty())
throw exceptions::no_recipient();
@@ -199,7 +196,8 @@ void SMTPTransport::send
}
// Prepare sending of message data
- commands->addCommand(SMTPCommand::DATA());
+ if (sendDATACommand)
+ commands->addCommand(SMTPCommand::DATA());
// Read response for "RSET" command
if (needReset)
@@ -238,13 +236,29 @@ void SMTPTransport::send
}
// Read response for "DATA" command
- commands->writeToSocket(m_connection->getSocket());
-
- if ((resp = m_connection->readResponse())->getCode() != 354)
+ if (sendDATACommand)
{
- disconnect();
- throw exceptions::command_error(commands->getLastCommandSent()->getText(), resp->getText());
+ commands->writeToSocket(m_connection->getSocket());
+
+ if ((resp = m_connection->readResponse())->getCode() != 354)
+ {
+ disconnect();
+ throw exceptions::command_error(commands->getLastCommandSent()->getText(), resp->getText());
+ }
}
+}
+
+
+void SMTPTransport::send
+ (const mailbox& expeditor, const mailboxList& recipients,
+ utility::inputStream& is, const utility::stream::size_type size,
+ utility::progressListener* progress, const mailbox& sender)
+{
+ if (!isConnected())
+ throw exceptions::not_connected();
+
+ // Send message envelope
+ sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ true);
// Send the message data
// Stream copy with "\n." to "\n.." transformation
@@ -258,6 +272,8 @@ void SMTPTransport::send
// Send end-of-data delimiter
m_connection->getSocket()->sendRaw("\r\n.\r\n", 5);
+ ref <SMTPResponse> resp;
+
if ((resp = m_connection->readResponse())->getCode() != 250)
{
disconnect();
@@ -270,21 +286,39 @@ void SMTPTransport::send
(ref <vmime::message> msg, const mailbox& expeditor, const mailboxList& recipients,
utility::progressListener* progress, const mailbox& sender)
{
+ if (!isConnected())
+ throw exceptions::not_connected();
+
// Generate the message with Internationalized Email support,
// if this is supported by the SMTP server
- std::ostringstream oss;
- utility::outputStreamAdapter ossAdapter(oss);
-
generationContext ctx(generationContext::getDefaultContext());
ctx.setInternationalizedEmailSupport(m_connection->hasExtension("SMTPUTF8"));
- msg->generate(ctx, ossAdapter);
+ // If CHUNKING is not supported, generate the message to a temporary
+ // buffer then use the send() method which takes an inputStream
+ if (!m_connection->hasExtension("CHUNKING"))
+ {
+ std::ostringstream oss;
+ utility::outputStreamAdapter ossAdapter(oss);
+
+ msg->generate(ctx, ossAdapter);
+
+ const string& str(oss.str());
+
+ utility::inputStreamStringAdapter isAdapter(str);
+
+ send(expeditor, recipients, isAdapter, str.length(), progress, sender);
+ }
+
+ // Send message envelope
+ sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ false);
- const string& str(oss.str());
+ // Send the message by chunks
+ SMTPChunkingOutputStreamAdapter chunkStream(m_connection);
- utility::inputStreamStringAdapter isAdapter(str);
+ msg->generate(ctx, chunkStream);
- send(expeditor, recipients, isAdapter, str.length(), progress, sender);
+ chunkStream.flush();
}