From c6904bd7cf03f6cca92cf0d15aec02e7850e0276 Mon Sep 17 00:00:00 2001 From: vincent-richard Date: Sat, 3 Apr 2021 11:21:50 +0200 Subject: SMTP/DSN refactoring. --- src/vmime/net/dsnAttributes.cpp | 71 ---------------- src/vmime/net/dsnAttributes.hpp | 114 -------------------------- src/vmime/net/sendmail/sendmailTransport.cpp | 2 +- src/vmime/net/sendmail/sendmailTransport.hpp | 2 +- src/vmime/net/smtp/DSNAttributes.cpp | 73 +++++++++++++++++ src/vmime/net/smtp/DSNAttributes.hpp | 116 +++++++++++++++++++++++++++ src/vmime/net/smtp/SMTPCommand.cpp | 32 +++++--- src/vmime/net/smtp/SMTPCommand.hpp | 8 +- src/vmime/net/smtp/SMTPSendOptions.cpp | 61 ++++++++++++++ src/vmime/net/smtp/SMTPSendOptions.hpp | 100 +++++++++++++++++++++++ src/vmime/net/smtp/SMTPTransport.cpp | 32 ++++---- src/vmime/net/smtp/SMTPTransport.hpp | 6 +- src/vmime/net/smtp/smtp.hpp | 1 + src/vmime/net/transport.cpp | 22 +++-- src/vmime/net/transport.hpp | 23 ++++-- tests/net/smtp/SMTPCommandTest.cpp | 33 ++++++-- 16 files changed, 456 insertions(+), 240 deletions(-) delete mode 100644 src/vmime/net/dsnAttributes.cpp delete mode 100644 src/vmime/net/dsnAttributes.hpp create mode 100644 src/vmime/net/smtp/DSNAttributes.cpp create mode 100644 src/vmime/net/smtp/DSNAttributes.hpp create mode 100644 src/vmime/net/smtp/SMTPSendOptions.cpp create mode 100644 src/vmime/net/smtp/SMTPSendOptions.hpp diff --git a/src/vmime/net/dsnAttributes.cpp b/src/vmime/net/dsnAttributes.cpp deleted file mode 100644 index dc949b99..00000000 --- a/src/vmime/net/dsnAttributes.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2020 Jan Osusky -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 3 of -// the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Linking this library statically or dynamically with other modules is making -// a combined work based on this library. Thus, the terms and conditions of -// the GNU General Public License cover the whole combination. -// - -#include "vmime/config.hpp" - - -#if VMIME_HAVE_MESSAGING_FEATURES - - -#include "vmime/net/dsnAttributes.hpp" - - -namespace vmime { -namespace net { - - -dsnAttributes::dsnAttributes(const string& dsnNotify, const string& dsnRet, const string& dsnEnvelopId) - : m_notifications(dsnNotify), m_returnFormat(dsnRet), m_envelopId(dsnEnvelopId) { - -} - - -string dsnAttributes::getNotificationConditions() const { - - return m_notifications; -} - - -string dsnAttributes::getReturnFormat() const { - - return m_returnFormat; -} - - -string dsnAttributes::getEnvelopId() const { - - return m_envelopId; -} - - -bool dsnAttributes::isEmpty() const { - - return m_notifications.empty() && m_returnFormat.empty() && m_envelopId.empty(); -} - - -} // net -} // vmime - - -#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/src/vmime/net/dsnAttributes.hpp b/src/vmime/net/dsnAttributes.hpp deleted file mode 100644 index 945da287..00000000 --- a/src/vmime/net/dsnAttributes.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2020 Jan Osusky -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 3 of -// the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Linking this library statically or dynamically with other modules is making -// a combined work based on this library. Thus, the terms and conditions of -// the GNU General Public License cover the whole combination. -// - -#ifndef VMIME_NET_DSNATTRIBUTES_HPP_INCLUDED -#define VMIME_NET_DSNATTRIBUTES_HPP_INCLUDED - - -#include "vmime/config.hpp" - - -#if VMIME_HAVE_MESSAGING_FEATURES - - -#include - -#include "vmime/types.hpp" - - -namespace vmime { -namespace net { - - -/** Holds a set of attributes for Delivery Status Notifications (DSN). - */ -class VMIME_EXPORT dsnAttributes : public object { - -public: - - /** Constructs an empty dsnAttributes object. - */ - dsnAttributes() = default; - - /** Constructs a new dsnAttributes object by copying an existing object. - * - * @param dsn object to copy - */ - dsnAttributes(const dsnAttributes& dsn) = default; - - /** Constructs a new dsnAttributes object by moving an existing object. - * - * @param dsn object (Rvalue reference) to move from. - */ - dsnAttributes(dsnAttributes&& dsn) = default; - - ~dsnAttributes() = default; - - /** Constructs a new dsnAttributes object by specifying the attributes. - * - * @param dsnNotify comma separated list of notification conditions as specified in RFC 1891 - * @param dsnRet content of DSN - full message or headers only ("FULL" or "HDRS") - * @param dsnEnvelopId envelop ID to be able to pair the DSN with original message (plain text not in "<" ">") - */ - dsnAttributes(const string& dsnNotify, const string& dsnRet, const string& dsnEnvelopId); - - /** Returns comma separated list of notification conditions as specified in RFC 1891 - * - * @return comma separated list of notification conditions as specified in RFC 1891 - */ - string getNotificationConditions() const; - - /** Returns requested format of the notification (RET parameter of the ESMTP MAIL command). - * - * @return requested format of the notification. - */ - string getReturnFormat() const; - - /** Returns envelop ID used to pair the DSN with the original message. - * - * @return envelop ID used to pair the DSN with the original message. - */ - string getEnvelopId() const; - - /** Returns whether the object is empty, and no attribute has been set. - * - * @return true if object is empty, or false otherwise - */ - bool isEmpty() const; - -private: - - string m_notifications; - string m_returnFormat; - string m_envelopId; -}; - - -} // net -} // vmime - - -#endif // VMIME_HAVE_MESSAGING_FEATURES - - -#endif // VMIME_NET_DSNATTRIBUTES_HPP_INCLUDED diff --git a/src/vmime/net/sendmail/sendmailTransport.cpp b/src/vmime/net/sendmail/sendmailTransport.cpp index 7010fd85..8b8b7272 100644 --- a/src/vmime/net/sendmail/sendmailTransport.cpp +++ b/src/vmime/net/sendmail/sendmailTransport.cpp @@ -149,7 +149,7 @@ void sendmailTransport::send( const size_t size, utility::progressListener* progress, const mailbox& sender, - const dsnAttributes& /*dsnAttrs*/ + const sendOptions& /* options */ ) { // If no recipient/expeditor was found, throw an exception diff --git a/src/vmime/net/sendmail/sendmailTransport.hpp b/src/vmime/net/sendmail/sendmailTransport.hpp index ce2cfe99..b313516e 100644 --- a/src/vmime/net/sendmail/sendmailTransport.hpp +++ b/src/vmime/net/sendmail/sendmailTransport.hpp @@ -74,7 +74,7 @@ public: const size_t size, utility::progressListener* progress = NULL, const mailbox& sender = mailbox(), - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ); bool isSecuredConnection() const; diff --git a/src/vmime/net/smtp/DSNAttributes.cpp b/src/vmime/net/smtp/DSNAttributes.cpp new file mode 100644 index 00000000..3181baeb --- /dev/null +++ b/src/vmime/net/smtp/DSNAttributes.cpp @@ -0,0 +1,73 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2020 Jan Osusky +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/smtp/DSNAttributes.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +DSNAttributes::DSNAttributes(const string& dsnNotify, const string& dsnRet, const string& dsnEnvelopId) + : m_notifications(dsnNotify), m_returnFormat(dsnRet), m_envelopId(dsnEnvelopId) { + +} + + +string DSNAttributes::getNotificationConditions() const { + + return m_notifications; +} + + +string DSNAttributes::getReturnFormat() const { + + return m_returnFormat; +} + + +string DSNAttributes::getEnvelopId() const { + + return m_envelopId; +} + + +bool DSNAttributes::isEmpty() const { + + return m_notifications.empty() && m_returnFormat.empty() && m_envelopId.empty(); +} + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/src/vmime/net/smtp/DSNAttributes.hpp b/src/vmime/net/smtp/DSNAttributes.hpp new file mode 100644 index 00000000..55164a59 --- /dev/null +++ b/src/vmime/net/smtp/DSNAttributes.hpp @@ -0,0 +1,116 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2020 Jan Osusky +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_DSNATTRIBUTES_HPP_INCLUDED +#define VMIME_NET_SMTP_DSNATTRIBUTES_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include + +#include "vmime/types.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +/** Holds a set of attributes for Delivery Status Notifications (DSN). + */ +class VMIME_EXPORT DSNAttributes : public object { + +public: + + /** Constructs an empty DSNAttributes object. + */ + DSNAttributes() = default; + + /** Constructs a new DSNAttributes object by copying an existing object. + * + * @param dsn object to copy + */ + DSNAttributes(const DSNAttributes& dsn) = default; + + /** Constructs a new DSNAttributes object by moving an existing object. + * + * @param dsn object (Rvalue reference) to move from. + */ + DSNAttributes(DSNAttributes&& dsn) = default; + + ~DSNAttributes() = default; + + /** Constructs a new DSNAttributes object by specifying the attributes. + * + * @param dsnNotify comma separated list of notification conditions as specified in RFC 1891 + * @param dsnRet content of DSN - full message or headers only ("FULL" or "HDRS") + * @param dsnEnvelopId envelop ID to be able to pair the DSN with original message (plain text not in "<" ">") + */ + DSNAttributes(const string& dsnNotify, const string& dsnRet, const string& dsnEnvelopId); + + /** Returns comma separated list of notification conditions as specified in RFC 1891 + * + * @return comma separated list of notification conditions as specified in RFC 1891 + */ + string getNotificationConditions() const; + + /** Returns requested format of the notification (RET parameter of the ESMTP MAIL command). + * + * @return requested format of the notification. + */ + string getReturnFormat() const; + + /** Returns envelop ID used to pair the DSN with the original message. + * + * @return envelop ID used to pair the DSN with the original message. + */ + string getEnvelopId() const; + + /** Returns whether the object is empty, and no attribute has been set. + * + * @return true if object is empty, or false otherwise + */ + bool isEmpty() const; + +private: + + string m_notifications; + string m_returnFormat; + string m_envelopId; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_NET_SMTP_DSNATTRIBUTES_HPP_INCLUDED diff --git a/src/vmime/net/smtp/SMTPCommand.cpp b/src/vmime/net/smtp/SMTPCommand.cpp index 5e533d16..c636d4bd 100644 --- a/src/vmime/net/smtp/SMTPCommand.cpp +++ b/src/vmime/net/smtp/SMTPCommand.cpp @@ -100,16 +100,20 @@ shared_ptr SMTPCommand::STARTTLS() { // static -shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, - const std::string& dsnRet, const std::string& dsnEnvelopId) { +shared_ptr SMTPCommand::MAIL( + const mailbox& mbox, const bool utf8, + const shared_ptr & dsnAttrs +) { - return MAIL(mbox, utf8, 0, dsnRet, dsnEnvelopId); + return MAIL(mbox, utf8, 0, dsnAttrs); } // static -shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, const size_t size, - const std::string& dsnRet, const std::string& dsnEnvelopId) { +shared_ptr SMTPCommand::MAIL( + const mailbox& mbox, const bool utf8, const size_t size, + const shared_ptr & dsnAttrs +) { std::ostringstream cmd; cmd.imbue(std::locale::classic()); @@ -127,11 +131,11 @@ shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, cmd << ">"; - if (!dsnRet.empty()) { - cmd << " " << dsn::RET << "=" << dsnRet; + if (dsnAttrs && !dsnAttrs->getReturnFormat().empty()) { + cmd << " " << dsn::RET << "=" << dsnAttrs->getReturnFormat(); } - if (!dsnEnvelopId.empty()) { - cmd << " " << dsn::ENVID << "=<" << dsnEnvelopId << ">"; + if (dsnAttrs && !dsnAttrs->getEnvelopId().empty()) { + cmd << " " << dsn::ENVID << "=<" << dsnAttrs->getEnvelopId() << ">"; } if (utf8) { @@ -147,8 +151,10 @@ shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, // static -shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8, - const string& dsnNotify) { +shared_ptr SMTPCommand::RCPT( + const mailbox& mbox, const bool utf8, + const shared_ptr & dsnAttrs +) { std::ostringstream cmd; cmd.imbue(std::locale::classic()); @@ -166,8 +172,8 @@ shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8, cmd << ">"; - if (!dsnNotify.empty()) { - cmd << " " << dsn::NOTIFY << "=" << dsnNotify; + if (dsnAttrs && !dsnAttrs->getNotificationConditions().empty()) { + cmd << " " << dsn::NOTIFY << "=" << dsnAttrs->getNotificationConditions(); } return createCommand(cmd.str()); diff --git a/src/vmime/net/smtp/SMTPCommand.hpp b/src/vmime/net/smtp/SMTPCommand.hpp index 9a32d1e7..57a32b86 100644 --- a/src/vmime/net/smtp/SMTPCommand.hpp +++ b/src/vmime/net/smtp/SMTPCommand.hpp @@ -34,6 +34,8 @@ #include "vmime/object.hpp" #include "vmime/base.hpp" +#include "DSNAttributes.hpp" + namespace vmime { @@ -64,11 +66,11 @@ public: static shared_ptr AUTH(const string& mechName, const std::string& initialResponse); static shared_ptr STARTTLS(); static shared_ptr MAIL(const mailbox& mbox, const bool utf8, - const std::string& dsnRet, const std::string& dsnEnvelopId); + const shared_ptr & dsnAttrs); static shared_ptr MAIL(const mailbox& mbox, const bool utf8, const size_t size, - const std::string& dsnRet, const std::string& dsnEnvelopId); + const shared_ptr & dsnAttrs); static shared_ptr RCPT(const mailbox& mbox, const bool utf8, - const std::string& dsnNotify); + const shared_ptr & dsnAttrs); static shared_ptr RSET(); static shared_ptr DATA(); static shared_ptr BDAT(const size_t chunkSize, const bool last); diff --git a/src/vmime/net/smtp/SMTPSendOptions.cpp b/src/vmime/net/smtp/SMTPSendOptions.cpp new file mode 100644 index 00000000..215ed6c0 --- /dev/null +++ b/src/vmime/net/smtp/SMTPSendOptions.cpp @@ -0,0 +1,61 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2020 Vincent Richard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/smtp/SMTPSendOptions.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +void SMTPSendOptions::setDSNAttributes(const shared_ptr & dsnAttribs) { + + m_dsnAttribs = dsnAttribs; +} + + +const shared_ptr SMTPSendOptions::getDSNAttributes() { + + return m_dsnAttribs; +} + + +const shared_ptr SMTPSendOptions::getDSNAttributes() const { + + return m_dsnAttribs; +} + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/src/vmime/net/smtp/SMTPSendOptions.hpp b/src/vmime/net/smtp/SMTPSendOptions.hpp new file mode 100644 index 00000000..e683ca23 --- /dev/null +++ b/src/vmime/net/smtp/SMTPSendOptions.hpp @@ -0,0 +1,100 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2020 Vincent Richard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPSENDOPTIONS_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPSENDOPTIONS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/transport.hpp" + +#include "vmime/net/smtp/DSNAttributes.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +/** Holds options for sending messages over SMTP. + */ +class VMIME_EXPORT SMTPSendOptions : public transport::sendOptions { + +public: + + /** Constructs an empty SMTPSendOptions object. + */ + SMTPSendOptions() = default; + + /** Constructs a new SMTPSendOptions object by copying an existing object. + * + * @param dsn object to copy + */ + SMTPSendOptions(const SMTPSendOptions& dsn) = default; + + /** Constructs a new SMTPSendOptions object by moving an existing object. + * + * @param dsn object (Rvalue reference) to move from. + */ + SMTPSendOptions(SMTPSendOptions&& dsn) = default; + + ~SMTPSendOptions() = default; + + /** Set DSN attributes to use when sending a message. + * + * @param dsnAttribs DSN attributes + */ + void setDSNAttributes(const shared_ptr & dsnAttribs); + + /** Return DSN attributes used when sending a message (const version). + * + * @return DSN attributes, if set + */ + const shared_ptr getDSNAttributes() const; + + /** Return DSN attributes used when sending a message. + * + * @return DSN attributes, if set + */ + const shared_ptr getDSNAttributes(); + +private: + + shared_ptr m_dsnAttribs; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_NET_SMTP_SMTPSENDOPTIONS_HPP_INCLUDED diff --git a/src/vmime/net/smtp/SMTPTransport.cpp b/src/vmime/net/smtp/SMTPTransport.cpp index 561bd592..882b8d37 100644 --- a/src/vmime/net/smtp/SMTPTransport.cpp +++ b/src/vmime/net/smtp/SMTPTransport.cpp @@ -33,6 +33,7 @@ #include "vmime/net/smtp/SMTPCommandSet.hpp" #include "vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp" #include "vmime/net/smtp/SMTPExceptions.hpp" +#include "vmime/net/smtp/SMTPSendOptions.hpp" #include "vmime/exception.hpp" #include "vmime/mailboxList.hpp" @@ -184,9 +185,11 @@ void SMTPTransport::sendEnvelope( const mailbox& sender, bool sendDATACommand, const size_t size, - const dsnAttributes& dsnAttrs + const sendOptions& options ) { + auto opts = dynamic_cast (&options); + // If no recipient/expeditor was found, throw an exception if (recipients.isEmpty()) { throw exceptions::no_recipient(); @@ -195,7 +198,7 @@ void SMTPTransport::sendEnvelope( } // If DSN extension is used, ensure it is supported by the server - if (!dsnAttrs.isEmpty() && !m_connection->hasExtension("DSN")) { + if (opts && opts->getDSNAttributes() && !m_connection->hasExtension("DSN")) { throw SMTPDSNExtensionNotSupportedException(); } @@ -237,8 +240,7 @@ void SMTPTransport::sendEnvelope( commands->addCommand( SMTPCommand::MAIL( sender, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0, - dsnAttrs.getNotificationConditions(), - dsnAttrs.getEnvelopId() + opts ? opts->getDSNAttributes() : nullptr ) ); @@ -247,8 +249,7 @@ void SMTPTransport::sendEnvelope( commands->addCommand( SMTPCommand::MAIL( expeditor, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0, - dsnAttrs.getNotificationConditions(), - dsnAttrs.getEnvelopId() + opts ? opts->getDSNAttributes() : nullptr ) ); } @@ -260,8 +261,12 @@ void SMTPTransport::sendEnvelope( for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { const mailbox& mbox = *recipients.getMailboxAt(i); - commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8 && needSMTPUTF8, - dsnAttrs.getNotificationConditions())); + commands->addCommand( + SMTPCommand::RCPT( + mbox, hasSMTPUTF8 && needSMTPUTF8, + opts ? opts->getDSNAttributes() : nullptr + ) + ); } // Prepare sending of message data @@ -388,7 +393,7 @@ void SMTPTransport::send( const size_t size, utility::progressListener* progress, const mailbox& sender, - const dsnAttributes& dsnAttrs + const sendOptions& options ) { if (!isConnected()) { @@ -396,8 +401,7 @@ void SMTPTransport::send( } // Send message envelope - sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ true, size, - dsnAttrs); + sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ true, size, options); // Send the message data // Stream copy with "\n." to "\n.." transformation @@ -430,7 +434,7 @@ void SMTPTransport::send( const mailboxList& recipients, utility::progressListener* progress, const mailbox& sender, - const dsnAttributes& dsnAttrs + const sendOptions& options ) { if (!isConnected()) { @@ -457,14 +461,14 @@ void SMTPTransport::send( utility::inputStreamStringAdapter isAdapter(str); - send(expeditor, recipients, isAdapter, str.length(), progress, sender, dsnAttrs); + send(expeditor, recipients, isAdapter, str.length(), progress, sender, options); return; } // Send message envelope const size_t msgSize = msg->getGeneratedSize(ctx); - sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ false, msgSize, dsnAttrs); + sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ false, msgSize, options); // Send the message by chunks SMTPChunkingOutputStreamAdapter chunkStream(m_connection, msgSize, progress); diff --git a/src/vmime/net/smtp/SMTPTransport.hpp b/src/vmime/net/smtp/SMTPTransport.hpp index cd7c712d..6dc118aa 100644 --- a/src/vmime/net/smtp/SMTPTransport.hpp +++ b/src/vmime/net/smtp/SMTPTransport.hpp @@ -79,7 +79,7 @@ public: const size_t size, utility::progressListener* progress = NULL, const mailbox& sender = mailbox(), - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ); void send( @@ -88,7 +88,7 @@ public: const mailboxList& recipients, utility::progressListener* progress = NULL, const mailbox& sender = mailbox(), - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ); bool isSecuredConnection() const; @@ -118,7 +118,7 @@ private: const mailbox& sender, bool sendDATACommand, const size_t size, - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ); diff --git a/src/vmime/net/smtp/smtp.hpp b/src/vmime/net/smtp/smtp.hpp index 4c0b17d7..8b7fd7b8 100644 --- a/src/vmime/net/smtp/smtp.hpp +++ b/src/vmime/net/smtp/smtp.hpp @@ -28,6 +28,7 @@ #include "vmime/net/smtp/SMTPTransport.hpp" #include "vmime/net/smtp/SMTPSTransport.hpp" #include "vmime/net/smtp/SMTPExceptions.hpp" +#include "vmime/net/smtp/SMTPSendOptions.hpp" #endif // VMIME_NET_SMTP_SMTP_HPP_INCLUDED diff --git a/src/vmime/net/transport.cpp b/src/vmime/net/transport.cpp index 0991302b..c2260b2a 100644 --- a/src/vmime/net/transport.cpp +++ b/src/vmime/net/transport.cpp @@ -137,7 +137,7 @@ static void extractMailboxes( void transport::send( const shared_ptr & msg, utility::progressListener* progress, - const dsnAttributes& dsnAttrs + const sendOptions& options ) { // Extract expeditor @@ -222,7 +222,7 @@ void transport::send( } headerExchanger(msg, hdr); - send(msg, expeditor, recipients, progress, sender, dsnAttrs); + send(msg, expeditor, recipients, progress, sender, options); } @@ -232,7 +232,7 @@ void transport::send( const mailboxList& recipients, utility::progressListener* progress, const mailbox& sender, - const dsnAttributes& dsnAttrs + const sendOptions& options ) { // Generate the message, "stream" it and delegate the sending @@ -246,8 +246,7 @@ void transport::send( utility::inputStreamStringAdapter isAdapter(str); - send(expeditor, recipients, isAdapter, str.length(), progress, sender, - dsnAttrs); + send(expeditor, recipients, isAdapter, str.length(), progress, sender, options); } @@ -257,6 +256,19 @@ transport::Type transport::getType() const { } +// sendOptions + + +transport::sendOptions::sendOptions() { + +} + + +transport::sendOptions::~sendOptions() { + +} + + } // net } // vmime diff --git a/src/vmime/net/transport.hpp b/src/vmime/net/transport.hpp index daa4717f..c19695df 100644 --- a/src/vmime/net/transport.hpp +++ b/src/vmime/net/transport.hpp @@ -31,7 +31,6 @@ #if VMIME_HAVE_MESSAGING_FEATURES -#include "vmime/net/dsnAttributes.hpp" #include "vmime/net/service.hpp" #include "vmime/utility/stream.hpp" @@ -64,18 +63,28 @@ protected: public: + /** Holds a set of options that can be passed to send() methods. + */ + class VMIME_EXPORT sendOptions { + + public: + + sendOptions(); + virtual ~sendOptions(); + }; + /** Send a message over this transport service. * The default implementation simply generates the whole message into * a string buffer and "streams" it via a inputStreamStringAdapter. * * @param msg message to send * @param progress progress listener, or NULL if not used - * @param dsnAttributes attributes for Delivery Status Notification (if needed) + * @param options sending options */ virtual void send( const shared_ptr & msg, utility::progressListener* progress = NULL, - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ); /** Send a message over this transport service. @@ -86,7 +95,7 @@ public: * @param size size of the message data * @param progress progress listener, or NULL if not used * @param sender envelope sender (if empty, expeditor will be used) - * @param dsnAttributes attributes for Delivery Status Notification (if needed) + * @param options sending options */ virtual void send( const mailbox& expeditor, @@ -95,7 +104,7 @@ public: const size_t size, utility::progressListener* progress = NULL, const mailbox& sender = mailbox(), - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ) = 0; /** Send a message over this transport service. @@ -107,7 +116,7 @@ public: * @param recipients list of recipient mailboxes * @param progress progress listener, or NULL if not used * @param sender envelope sender (if empty, expeditor will be used) - * @param dsnAttributes attributes for Delivery Status Notification (if needed) + * @param options sending options */ virtual void send( const shared_ptr & msg, @@ -115,7 +124,7 @@ public: const mailboxList& recipients, utility::progressListener* progress = NULL, const mailbox& sender = mailbox(), - const dsnAttributes& dsnAttrs = dsnAttributes() + const sendOptions& options = sendOptions() ); diff --git a/tests/net/smtp/SMTPCommandTest.cpp b/tests/net/smtp/SMTPCommandTest.cpp index ecaf292c..f4b6c082 100644 --- a/tests/net/smtp/SMTPCommandTest.cpp +++ b/tests/net/smtp/SMTPCommandTest.cpp @@ -24,6 +24,7 @@ #include "tests/testUtils.hpp" #include "vmime/net/smtp/SMTPCommand.hpp" +#include "vmime/net/smtp/DSNAttributes.hpp" using namespace vmime::net::smtp; @@ -114,7 +115,9 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testMAIL() { - vmime::shared_ptr cmd = SMTPCommand::MAIL(vmime::mailbox("me@vmime.org"), false, "FULL", "dsn-unique-id"); + auto dsnAttrs = vmime::make_shared ("", "FULL", "dsn-unique-id"); + + vmime::shared_ptr cmd = SMTPCommand::MAIL(vmime::mailbox("me@vmime.org"), false, dsnAttrs); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MAIL FROM: RET=FULL ENVID=", cmd->getText()); @@ -122,8 +125,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testMAIL_Encoded() { + auto dsnAttrs = vmime::make_shared ("", "FULL", "dsn-unique-id"); + vmime::shared_ptr cmd = SMTPCommand::MAIL( - vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false, "FULL", "dsn-unique-id" + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false, dsnAttrs ); VASSERT_NOT_NULL("Not null", cmd); @@ -132,8 +137,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testMAIL_UTF8() { + auto dsnAttrs = vmime::make_shared ("", "FULL", "dsn-unique-id"); + vmime::shared_ptr cmd = SMTPCommand::MAIL( - vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, "FULL", "dsn-unique-id" + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, dsnAttrs ); VASSERT_NOT_NULL("Not null", cmd); @@ -142,8 +149,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testMAIL_SIZE() { + auto dsnAttrs = vmime::make_shared ("", "FULL", "dsn-unique-id"); + vmime::shared_ptr cmd = SMTPCommand::MAIL( - vmime::mailbox("me@vmime.org"), false, 123456789, "FULL", "dsn-unique-id" + vmime::mailbox("me@vmime.org"), false, 123456789, dsnAttrs ); VASSERT_NOT_NULL("Not null", cmd); @@ -152,8 +161,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testMAIL_SIZE_UTF8() { + auto dsnAttrs = vmime::make_shared ("", "FULL", "dsn-unique-id"); + vmime::shared_ptr cmd = SMTPCommand::MAIL( - vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, 123456789, "FULL", "dsn-unique-id" + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, 123456789, dsnAttrs ); VASSERT_NOT_NULL("Not null", cmd); @@ -162,8 +173,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testRCPT() { + auto dsnAttrs = vmime::make_shared ("NEVER", "", ""); + vmime::shared_ptr cmd = - SMTPCommand::RCPT(vmime::mailbox("someone@vmime.org"), false, "NEVER"); + SMTPCommand::RCPT(vmime::mailbox("someone@vmime.org"), false, dsnAttrs); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RCPT TO: NOTIFY=NEVER", cmd->getText()); @@ -171,8 +184,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testRCPT_Encoded() { + auto dsnAttrs = vmime::make_shared ("NEVER", "", ""); + vmime::shared_ptr cmd = SMTPCommand::RCPT( - vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false, "NEVER" + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false, dsnAttrs ); VASSERT_NOT_NULL("Not null", cmd); @@ -181,8 +196,10 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) void testRCPT_UTF8() { + auto dsnAttrs = vmime::make_shared ("NEVER", "", ""); + vmime::shared_ptr cmd = SMTPCommand::RCPT( - vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, "NEVER" + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, dsnAttrs ); VASSERT_NOT_NULL("Not null", cmd); -- cgit v1.2.3