MailMessage: attachments saving and read/write

MailMessage: attachments saving support and consistent read/write
This commit is contained in:
aleks-f
2013-03-10 23:36:04 -05:00
parent 46c3d74c5f
commit ad077b8f3f
25 changed files with 600 additions and 52 deletions

View File

@@ -37,8 +37,11 @@
#include "Poco/Net/MailRecipient.h"
#include "Poco/Net/PartHandler.h"
#include "Poco/Net/StringPartSource.h"
#include "Poco/Net/PartStore.h"
#include "Poco/Net/MediaType.h"
#include "Poco/Timestamp.h"
#include "Poco/FileStream.h"
#include "Poco/String.h"
#include <sstream>
#include <vector>
@@ -49,7 +52,12 @@ using Poco::Net::MessageHeader;
using Poco::Net::PartHandler;
using Poco::Net::MediaType;
using Poco::Net::StringPartSource;
using Poco::Net::FilePartStoreFactory;
using Poco::Net::FilePartStore;
using Poco::Timestamp;
using Poco::FileInputStream;
using Poco::replaceInPlace;
using Poco::icompare;
namespace
@@ -135,6 +143,7 @@ void MailMessageTest::testWriteQP()
std::ostringstream str;
message.write(str);
std::string s = str.str();
assert (s ==
"Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n"
"Content-Type: text/plain\r\n"
@@ -302,9 +311,9 @@ void MailMessageTest::testWriteMultiPart()
"VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n"
"--$--\r\n"
);
std::string::size_type p2 = s.rfind("--");
std::string::size_type p1 = s.rfind("--", p2 - 1);
std::string boundary(s, p1 + 2, p2 - 2 - p1);
std::string::size_type p1 = s.find('=') + 1;
std::string::size_type p2 = s.find('\r', p1);
std::string boundary(s, p1, p2 - p1);
std::string msg;
for (std::string::const_iterator it = rawMsg.begin(); it != rawMsg.end(); ++it)
{
@@ -313,6 +322,7 @@ void MailMessageTest::testWriteMultiPart()
else
msg += *it;
}
assert (s == msg);
}
@@ -416,6 +426,111 @@ void MailMessageTest::testReadMultiPart()
}
void MailMessageTest::testReadWriteMultiPart()
{
std::string msgin(
"Content-Type: multipart/mixed; boundary=MIME_boundary_31E8A8D61DF53389\r\n"
"Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n"
"From: poco@appinf.com\r\n"
"Mime-Version: 1.0\r\n"
"Subject: Test Message\r\n"
"To: John Doe <john.doe@no.where>\r\n"
"\r\n"
"--MIME_boundary_31E8A8D61DF53389\r\n"
"Content-Disposition: inline\r\n"
"Content-Transfer-Encoding: 8bit\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"Hello World!\r\n"
"\r\n"
"--MIME_boundary_31E8A8D61DF53389\r\n"
"Content-Disposition: attachment; filename=sample.dat\r\n"
"Content-ID: abcd1234\r\n"
"Content-Transfer-Encoding: base64\r\n"
"Content-Type: application/octet-stream; name=sample\r\n"
"\r\n"
"VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n"
"--MIME_boundary_31E8A8D61DF53389--\r\n"
);
std::istringstream istr(msgin);
std::ostringstream ostr;
MailMessage message;
message.read(istr);
message.write(ostr);
std::string msgout(ostr.str());
assert (msgout == msgin);
}
void MailMessageTest::testReadWriteMultiPartStore()
{
std::string msgin(
"Content-Type: multipart/mixed; boundary=MIME_boundary_31E8A8D61DF53389\r\n"
"Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n"
"From: poco@appinf.com\r\n"
"Mime-Version: 1.0\r\n"
"Subject: Test Message\r\n"
"To: John Doe <john.doe@no.where>\r\n"
"\r\n"
"--MIME_boundary_31E8A8D61DF53389\r\n"
"Content-Disposition: inline\r\n"
"Content-Transfer-Encoding: 8bit\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"Hello World!\r\n"
"\r\n"
"--MIME_boundary_31E8A8D61DF53389\r\n"
"Content-Disposition: attachment; filename=sample.dat\r\n"
"Content-ID: abcd1234\r\n"
"Content-Transfer-Encoding: base64\r\n"
"Content-Type: application/octet-stream; name=sample\r\n"
"\r\n"
"VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n"
"--MIME_boundary_31E8A8D61DF53389--\r\n"
);
std::istringstream istr(msgin);
std::ostringstream ostr;
FilePartStoreFactory pfsf;
MailMessage message(&pfsf);
message.read(istr);
MailMessage::PartVec::const_iterator it = message.parts().begin();
MailMessage::PartVec::const_iterator end = message.parts().end();
for (; it != end; ++it)
{
FilePartStore* fps = dynamic_cast<FilePartStore*>(it->pSource);
if (fps && fps->filename().size())
{
std::string filename = fps->filename();
assert (filename == "sample.dat");
std::string path = fps->path();
// for security reasons, the filesystem temporary
// filename is not the same as attachment name
std::size_t sz = (path.size() > filename.size()) ? filename.size() : path.size();
assert (0 != icompare(path, path.size() - sz, sz, path));
Poco::FileInputStream fis(path);
assert (fis.good());
std::string read;
std::string line;
while (std::getline(fis, line)) read += line;
assert (!read.empty());
assert (read == "This is some binary data. Really.");
}
}
message.write(ostr);
std::string msgout(ostr.str());
assert (msgout == msgin);
}
void MailMessageTest::testEncodeWord()
{
std::string plain("this is pure ASCII");
@@ -460,6 +575,8 @@ CppUnit::Test* MailMessageTest::suite()
CppUnit_addTest(pSuite, MailMessageTest, testReadQP);
CppUnit_addTest(pSuite, MailMessageTest, testRead8Bit);
CppUnit_addTest(pSuite, MailMessageTest, testReadMultiPart);
CppUnit_addTest(pSuite, MailMessageTest, testReadWriteMultiPart);
CppUnit_addTest(pSuite, MailMessageTest, testReadWriteMultiPartStore);
CppUnit_addTest(pSuite, MailMessageTest, testEncodeWord);
return pSuite;

View File

@@ -51,6 +51,8 @@ public:
void testWriteBase64();
void testWriteManyRecipients();
void testWriteMultiPart();
void testReadWriteMultiPart();
void testReadWriteMultiPartStore();
void testReadQP();
void testRead8Bit();
void testReadMultiPart();