mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 10:32:57 +01:00
SF #3538785: SMTPClientSession::sendMessage() should take recipient list
This commit is contained in:
parent
0466c67ff2
commit
d56a7a1ee6
@ -21,6 +21,7 @@ Release 1.5.0 (2012-07-30)
|
||||
- IPAddress bitwise operators (&,|,^,~)
|
||||
- IPAddress BinaryReader/Writer << and >> operators
|
||||
- IPAddress force IPv6 always lowercase (RFC 5952)
|
||||
- fixed SF#3538785: SMTPClientSession::sendMessage() should take recipient list
|
||||
|
||||
Release 1.4.4 (2012-07-??)
|
||||
==========================
|
||||
|
@ -69,7 +69,7 @@ class Net_API MailMessage: public MessageHeader
|
||||
/// encodings are supported: 7bit, 8bit, quoted-printable
|
||||
/// and base64.
|
||||
{
|
||||
public:
|
||||
public:
|
||||
typedef std::vector<MailRecipient> Recipients;
|
||||
|
||||
enum ContentDisposition
|
||||
@ -94,6 +94,9 @@ public:
|
||||
|
||||
void addRecipient(const MailRecipient& recipient);
|
||||
/// Adds a recipient for the message.
|
||||
|
||||
void setRecipients(const Recipients& recipient);
|
||||
/// Clears existing and sets new recipient list for the message.
|
||||
|
||||
const Recipients& recipients() const;
|
||||
/// Returns the recipients of the message.
|
||||
|
@ -59,6 +59,8 @@ class Net_API SMTPClientSession
|
||||
/// client for sending e-mail messages.
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::string> Recipients;
|
||||
|
||||
enum
|
||||
{
|
||||
SMTP_PORT = 25
|
||||
@ -130,7 +132,18 @@ public:
|
||||
void sendMessage(const MailMessage& message);
|
||||
/// Sends the given mail message by sending a MAIL FROM command,
|
||||
/// a RCPT TO command for every recipient, and a DATA command with
|
||||
/// the message headers and content.
|
||||
/// the message headers and content. Using this function results in
|
||||
/// RCPT TO commands list generated from the recipient list supplied
|
||||
/// with the message itself.
|
||||
///
|
||||
/// Throws a SMTPException in case of a SMTP-specific error, or a
|
||||
/// NetException in case of a general network communication failure.
|
||||
|
||||
void sendMessage(const MailMessage& message, const Recipients& recipients);
|
||||
/// Sends the given mail message by sending a MAIL FROM command,
|
||||
/// a RCPT TO command for every recipient, and a DATA command with
|
||||
/// the message headers and content. Using this function results in
|
||||
/// message header being generated from the supplied recipients list.
|
||||
///
|
||||
/// Throws a SMTPException in case of a SMTP-specific error, or a
|
||||
/// NetException in case of a general network communication failure.
|
||||
@ -176,6 +189,9 @@ protected:
|
||||
DialogSocket& socket();
|
||||
|
||||
private:
|
||||
void sendCommands(const MailMessage& message, const Recipients* pRecipients = 0);
|
||||
void transportMessage(const MailMessage& message);
|
||||
|
||||
DialogSocket _socket;
|
||||
bool _isOpen;
|
||||
};
|
||||
|
@ -133,6 +133,12 @@ void MailMessage::addRecipient(const MailRecipient& recipient)
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setRecipients(const Recipients& recipients)
|
||||
{
|
||||
_recipients.assign(recipients.begin(), recipients.end());
|
||||
}
|
||||
|
||||
|
||||
void MailMessage::setSender(const std::string& sender)
|
||||
{
|
||||
set(HEADER_FROM, sender);
|
||||
|
@ -318,7 +318,7 @@ void SMTPClientSession::close()
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::sendMessage(const MailMessage& message)
|
||||
void SMTPClientSession::sendCommands(const MailMessage& message, const Recipients* pRecipients)
|
||||
{
|
||||
std::string response;
|
||||
int status = 0;
|
||||
@ -335,17 +335,55 @@ void SMTPClientSession::sendMessage(const MailMessage& message)
|
||||
{
|
||||
status = sendCommand("MAIL FROM:", fromField.substr(emailPos, fromField.size() - emailPos), response);
|
||||
}
|
||||
|
||||
if (!isPositiveCompletion(status)) throw SMTPException("Cannot send message", response, status);
|
||||
for (MailMessage::Recipients::const_iterator it = message.recipients().begin(); it != message.recipients().end(); ++it)
|
||||
|
||||
std::ostringstream recipient;
|
||||
if (pRecipients)
|
||||
{
|
||||
std::string recipient("<");
|
||||
recipient.append(it->getAddress());
|
||||
recipient.append(">");
|
||||
int status = sendCommand("RCPT TO:", recipient, response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException(std::string("Recipient rejected: ") + recipient, response, status);
|
||||
for (Recipients::const_iterator it = pRecipients->begin(); it != pRecipients->end(); ++it)
|
||||
{
|
||||
recipient << '<' << *it << '>';
|
||||
int status = sendCommand("RCPT TO:", recipient.str(), response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException(std::string("Recipient rejected: ") + recipient.str(), response, status);
|
||||
recipient.str("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (MailMessage::Recipients::const_iterator it = message.recipients().begin(); it != message.recipients().end(); ++it)
|
||||
{
|
||||
recipient << '<' << it->getAddress() << '>';
|
||||
int status = sendCommand("RCPT TO:", recipient.str(), response);
|
||||
if (!isPositiveCompletion(status)) throw SMTPException(std::string("Recipient rejected: ") + recipient.str(), response, status);
|
||||
recipient.str("");
|
||||
}
|
||||
}
|
||||
|
||||
status = sendCommand("DATA", response);
|
||||
if (!isPositiveIntermediate(status)) throw SMTPException("Cannot send message data", response, status);
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::sendMessage(const MailMessage& message)
|
||||
{
|
||||
sendCommands(message);
|
||||
transportMessage(message);
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::sendMessage(const MailMessage& message, const Recipients& recipients)
|
||||
{
|
||||
sendCommands(message, &recipients);
|
||||
transportMessage(message);
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSession::transportMessage(const MailMessage& message)
|
||||
{
|
||||
std::string response;
|
||||
int status = 0;
|
||||
|
||||
SocketOutputStream socketStream(_socket);
|
||||
MailOutputStream mailStream(socketStream);
|
||||
message.write(mailStream);
|
||||
|
@ -160,6 +160,141 @@ void SMTPClientSessionTest::testSend()
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSessionTest::testSendMultiRecipient()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost SMTP ready");
|
||||
server.addResponse("250 Hello localhost");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("354 Send data");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
session.login("localhost");
|
||||
|
||||
MailMessage message;
|
||||
message.setSender("john.doe@no.where");
|
||||
MailMessage::Recipients msgRecipients;
|
||||
msgRecipients.push_back(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, "jane.doe@no.where", "Jane Doe"));
|
||||
msgRecipients.push_back(MailRecipient(MailRecipient::CC_RECIPIENT, "jack.doe@no.where", "Jack Doe"));
|
||||
msgRecipients.push_back(MailRecipient(MailRecipient::BCC_RECIPIENT, "joe.doe@no.where", "Joe Doe"));
|
||||
message.setRecipients(msgRecipients);
|
||||
message.setSubject("Test Message");
|
||||
message.setContent("Hello\r\nblah blah\r\n\r\nJohn\r\n");
|
||||
|
||||
server.clearCommands();
|
||||
session.sendMessage(message);
|
||||
std::string cmd = server.popCommandWait();
|
||||
assert (cmd == "MAIL FROM: <john.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RCPT TO: <jane.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RCPT TO: <jack.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RCPT TO: <joe.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "DATA");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "CC: Jack Doe <jack.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Content-Transfer-Encoding: quoted-printable");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Content-Type: text/plain");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd.substr(0, 4) == "Date");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "From: john.doe@no.where");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Subject: Test Message");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "To: Jane Doe <jane.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Hello");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "blah blah");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "John");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == ".");
|
||||
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSessionTest::testMultiSeparateRecipient()
|
||||
{
|
||||
DialogServer server;
|
||||
server.addResponse("220 localhost SMTP ready");
|
||||
server.addResponse("250 Hello localhost");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("354 Send data");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("250 OK");
|
||||
server.addResponse("221 Bye");
|
||||
SMTPClientSession session("localhost", server.port());
|
||||
session.login("localhost");
|
||||
|
||||
MailMessage message;
|
||||
message.setSender("john.doe@no.where");
|
||||
MailMessage::Recipients msgRecipients;
|
||||
msgRecipients.push_back(MailRecipient(MailRecipient::PRIMARY_RECIPIENT, "jane.doe@no.where", "Jane Doe"));
|
||||
msgRecipients.push_back(MailRecipient(MailRecipient::CC_RECIPIENT, "jack.doe@no.where", "Jack Doe"));
|
||||
msgRecipients.push_back(MailRecipient(MailRecipient::CC_RECIPIENT, "joe.doe@no.where", "Joe Doe"));
|
||||
message.setRecipients(msgRecipients);
|
||||
message.setSubject("Test Message");
|
||||
message.setContent("Hello\r\nblah blah\r\n\r\nJohn\r\n");
|
||||
|
||||
SMTPClientSession::Recipients recipients;
|
||||
recipients.push_back("jill.doe@no.where");
|
||||
recipients.push_back("josh.doe@no.where");
|
||||
recipients.push_back("jake.doe@no.where");
|
||||
|
||||
server.clearCommands();
|
||||
session.sendMessage(message, recipients);
|
||||
std::string cmd = server.popCommandWait();
|
||||
assert (cmd == "MAIL FROM: <john.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RCPT TO: <jill.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RCPT TO: <josh.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "RCPT TO: <jake.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "DATA");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "CC: Jack Doe <jack.doe@no.where>, Joe Doe <joe.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Content-Transfer-Encoding: quoted-printable");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Content-Type: text/plain");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd.substr(0, 4) == "Date");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "From: john.doe@no.where");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Subject: Test Message");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "To: Jane Doe <jane.doe@no.where>");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "Hello");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "blah blah");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == "John");
|
||||
cmd = server.popCommandWait();
|
||||
assert (cmd == ".");
|
||||
|
||||
session.close();
|
||||
}
|
||||
|
||||
|
||||
void SMTPClientSessionTest::testSendFailed()
|
||||
{
|
||||
DialogServer server;
|
||||
@ -210,6 +345,8 @@ CppUnit::Test* SMTPClientSessionTest::suite()
|
||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testLoginHELO);
|
||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testLoginFailed);
|
||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSend);
|
||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSendMultiRecipient);
|
||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testMultiSeparateRecipient);
|
||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSendFailed);
|
||||
|
||||
return pSuite;
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
void testLoginHELO();
|
||||
void testLoginFailed();
|
||||
void testSend();
|
||||
void testSendMultiRecipient();
|
||||
void testMultiSeparateRecipient();
|
||||
void testSendFailed();
|
||||
|
||||
void setUp();
|
||||
|
Loading…
Reference in New Issue
Block a user