mirror of
https://github.com/pocoproject/poco.git
synced 2025-05-31 08:09:02 +02: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 bitwise operators (&,|,^,~)
|
||||||
- IPAddress BinaryReader/Writer << and >> operators
|
- IPAddress BinaryReader/Writer << and >> operators
|
||||||
- IPAddress force IPv6 always lowercase (RFC 5952)
|
- IPAddress force IPv6 always lowercase (RFC 5952)
|
||||||
|
- fixed SF#3538785: SMTPClientSession::sendMessage() should take recipient list
|
||||||
|
|
||||||
Release 1.4.4 (2012-07-??)
|
Release 1.4.4 (2012-07-??)
|
||||||
==========================
|
==========================
|
||||||
|
@ -95,6 +95,9 @@ public:
|
|||||||
void addRecipient(const MailRecipient& recipient);
|
void addRecipient(const MailRecipient& recipient);
|
||||||
/// Adds a recipient for the message.
|
/// 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;
|
const Recipients& recipients() const;
|
||||||
/// Returns the recipients of the message.
|
/// Returns the recipients of the message.
|
||||||
|
|
||||||
|
@ -59,6 +59,8 @@ class Net_API SMTPClientSession
|
|||||||
/// client for sending e-mail messages.
|
/// client for sending e-mail messages.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::vector<std::string> Recipients;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SMTP_PORT = 25
|
SMTP_PORT = 25
|
||||||
@ -130,7 +132,18 @@ public:
|
|||||||
void sendMessage(const MailMessage& message);
|
void sendMessage(const MailMessage& message);
|
||||||
/// Sends the given mail message by sending a MAIL FROM command,
|
/// Sends the given mail message by sending a MAIL FROM command,
|
||||||
/// a RCPT TO command for every recipient, and a DATA command with
|
/// 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
|
/// Throws a SMTPException in case of a SMTP-specific error, or a
|
||||||
/// NetException in case of a general network communication failure.
|
/// NetException in case of a general network communication failure.
|
||||||
@ -176,6 +189,9 @@ protected:
|
|||||||
DialogSocket& socket();
|
DialogSocket& socket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void sendCommands(const MailMessage& message, const Recipients* pRecipients = 0);
|
||||||
|
void transportMessage(const MailMessage& message);
|
||||||
|
|
||||||
DialogSocket _socket;
|
DialogSocket _socket;
|
||||||
bool _isOpen;
|
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)
|
void MailMessage::setSender(const std::string& sender)
|
||||||
{
|
{
|
||||||
set(HEADER_FROM, 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;
|
std::string response;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -335,17 +335,55 @@ void SMTPClientSession::sendMessage(const MailMessage& message)
|
|||||||
{
|
{
|
||||||
status = sendCommand("MAIL FROM:", fromField.substr(emailPos, fromField.size() - emailPos), response);
|
status = sendCommand("MAIL FROM:", fromField.substr(emailPos, fromField.size() - emailPos), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPositiveCompletion(status)) throw SMTPException("Cannot send message", response, status);
|
if (!isPositiveCompletion(status)) throw SMTPException("Cannot send message", response, status);
|
||||||
|
|
||||||
|
std::ostringstream recipient;
|
||||||
|
if (pRecipients)
|
||||||
|
{
|
||||||
|
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)
|
for (MailMessage::Recipients::const_iterator it = message.recipients().begin(); it != message.recipients().end(); ++it)
|
||||||
{
|
{
|
||||||
std::string recipient("<");
|
recipient << '<' << it->getAddress() << '>';
|
||||||
recipient.append(it->getAddress());
|
int status = sendCommand("RCPT TO:", recipient.str(), response);
|
||||||
recipient.append(">");
|
if (!isPositiveCompletion(status)) throw SMTPException(std::string("Recipient rejected: ") + recipient.str(), response, status);
|
||||||
int status = sendCommand("RCPT TO:", recipient, response);
|
recipient.str("");
|
||||||
if (!isPositiveCompletion(status)) throw SMTPException(std::string("Recipient rejected: ") + recipient, response, status);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status = sendCommand("DATA", response);
|
status = sendCommand("DATA", response);
|
||||||
if (!isPositiveIntermediate(status)) throw SMTPException("Cannot send message data", response, status);
|
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);
|
SocketOutputStream socketStream(_socket);
|
||||||
MailOutputStream mailStream(socketStream);
|
MailOutputStream mailStream(socketStream);
|
||||||
message.write(mailStream);
|
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()
|
void SMTPClientSessionTest::testSendFailed()
|
||||||
{
|
{
|
||||||
DialogServer server;
|
DialogServer server;
|
||||||
@ -210,6 +345,8 @@ CppUnit::Test* SMTPClientSessionTest::suite()
|
|||||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testLoginHELO);
|
CppUnit_addTest(pSuite, SMTPClientSessionTest, testLoginHELO);
|
||||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testLoginFailed);
|
CppUnit_addTest(pSuite, SMTPClientSessionTest, testLoginFailed);
|
||||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSend);
|
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSend);
|
||||||
|
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSendMultiRecipient);
|
||||||
|
CppUnit_addTest(pSuite, SMTPClientSessionTest, testMultiSeparateRecipient);
|
||||||
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSendFailed);
|
CppUnit_addTest(pSuite, SMTPClientSessionTest, testSendFailed);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
|
@ -50,6 +50,8 @@ public:
|
|||||||
void testLoginHELO();
|
void testLoginHELO();
|
||||||
void testLoginFailed();
|
void testLoginFailed();
|
||||||
void testSend();
|
void testSend();
|
||||||
|
void testSendMultiRecipient();
|
||||||
|
void testMultiSeparateRecipient();
|
||||||
void testSendFailed();
|
void testSendFailed();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user