POP3 client fails to retrieve message if content-type is absent #806; add multi-part attachment name retrieval

This commit is contained in:
Alex Fabijanic 2017-10-10 18:06:02 -05:00
parent 36e2a11311
commit ad1b75b30e
4 changed files with 50 additions and 17 deletions

View File

@ -65,12 +65,12 @@ namespace
/// in its entirety, including attachments.
{
}
~MultiPartHandler()
/// Destroys string part handler.
{
}
void handlePart(const MessageHeader& header, std::istream& stream)
/// Handles a part. If message pointer was provided at construction time,
/// the message pointed to will be properly populated so it could be written
@ -92,7 +92,7 @@ namespace
cte = MailMessage::ENCODING_BASE64;
}
std::string contentType = header.get(MailMessage::HEADER_CONTENT_TYPE, "");
std::string contentType = header.get(MailMessage::HEADER_CONTENT_TYPE, "text/plain; charset=us-ascii");
std::string contentDisp = header.get(MailMessage::HEADER_CONTENT_DISPOSITION, "");
std::string filename;
if (!contentDisp.empty())
@ -110,8 +110,8 @@ namespace
{
if (it->second == "inline")
_pMsg->addContent(pPS, cte);
else
_pMsg->addAttachment("", pPS, cte);
else
_pMsg->addAttachment(getPartName(header), pPS, cte);
added = true;
}
@ -134,7 +134,7 @@ namespace
StringTokenizer st(header, ";=", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
StringTokenizer::Iterator it = st.begin();
StringTokenizer::Iterator end = st.end();
for (; it != end; ++it) { if (*it == param) break; }
for (; it != end; ++it) { if (icompare(*it, param) == 0) break; }
if (it != end)
{
++it;
@ -144,6 +144,14 @@ namespace
return "";
}
std::string getPartName(const MessageHeader& header)
{
std::string ct = MailMessage::HEADER_CONTENT_TYPE;
if (header.has(ct))
return getParamFromHeader(header[ct], "name");
return "";
}
MailMessage* _pMsg;
};
@ -216,7 +224,7 @@ MailMessage::~MailMessage()
}
}
void MailMessage::addRecipient(const MailRecipient& recipient)
{
_recipients.push_back(recipient);
@ -272,13 +280,13 @@ void MailMessage::setContentType(const std::string& mediaType)
set(HEADER_CONTENT_TYPE, mediaType);
}
void MailMessage::setContentType(const MediaType& mediaType)
{
setContentType(mediaType.toString());
}
const std::string& MailMessage::getContentType() const
{
if (has(HEADER_CONTENT_TYPE))
@ -293,7 +301,7 @@ void MailMessage::setDate(const Poco::Timestamp& dateTime)
set(HEADER_DATE, DateTimeFormatter::format(dateTime, DateTimeFormat::RFC1123_FORMAT));
}
Poco::Timestamp MailMessage::getDate() const
{
const std::string& dateTime = get(HEADER_DATE);
@ -301,7 +309,7 @@ Poco::Timestamp MailMessage::getDate() const
return DateTimeParser::parse(dateTime, tzd).timestamp();
}
bool MailMessage::isMultipart() const
{
MediaType mediaType = getContentType();
@ -328,7 +336,7 @@ void MailMessage::addContent(PartSource* pSource, ContentTransferEncoding encodi
addPart("", pSource, CONTENT_INLINE, encoding);
}
void MailMessage::addAttachment(const std::string& name, PartSource* pSource, ContentTransferEncoding encoding)
{
addPart(name, pSource, CONTENT_ATTACHMENT, encoding);

View File

@ -88,7 +88,7 @@ int MultipartStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
buf.sbumpc(); // '\n'
}
return 0;
return 0;
}
else if (ch == '-' && buf.sgetc() == '-')
{
@ -218,11 +218,11 @@ bool MultipartReader::hasNextPart()
return (!_pMPI || !_pMPI->lastPart()) && _istr.good();
}
std::istream& MultipartReader::stream() const
{
poco_check_ptr (_pMPI);
return *_pMPI;
}

View File

@ -374,6 +374,28 @@ void MailMessageTest::testReadDefaultTransferEncoding()
}
void MailMessageTest::testReadDefaultContentType()
{
std::istringstream istr("Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n"
"From: poco@appinf.com\r\n"
"Subject: Test Message\r\n"
"To: John Doe <john.doe@no.where>\r\n"
"\r\n"
"Hello, world!\r\n"
"This is a test for the MailMessage class.\r\n"
);
MailMessage message;
message.read(istr);
assert (message.getSender() == "poco@appinf.com");
assert (message.getContentType() == "text/plain");
assert (message.getContent() == "Hello, world!\r\n"
"This is a test for the MailMessage class.\r\n"
);
}
void MailMessageTest::testRead8Bit()
{
std::istringstream istr(
@ -468,10 +490,10 @@ void MailMessageTest::testReadMultiPartWithAttachmentNames()
"VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n"
"--MIME_boundary_01234567--\r\n"
);
MailMessage message;
message.read(istr);
assert (message.parts().size() == 2);
assert (message.parts()[1].name == "sample");
assert (message.parts()[1].pSource->filename() == "sample.dat");
@ -667,8 +689,10 @@ CppUnit::Test* MailMessageTest::suite()
CppUnit_addTest(pSuite, MailMessageTest, testWriteMultiPart);
CppUnit_addTest(pSuite, MailMessageTest, testReadQP);
CppUnit_addTest(pSuite, MailMessageTest, testReadDefaultTransferEncoding);
CppUnit_addTest(pSuite, MailMessageTest, testReadDefaultContentType);
CppUnit_addTest(pSuite, MailMessageTest, testRead8Bit);
CppUnit_addTest(pSuite, MailMessageTest, testReadMultiPart);
CppUnit_addTest(pSuite, MailMessageTest, testReadMultiPartWithAttachmentNames);
CppUnit_addTest(pSuite, MailMessageTest, testReadMultiPartDefaultTransferEncoding);
CppUnit_addTest(pSuite, MailMessageTest, testReadWriteMultiPart);
CppUnit_addTest(pSuite, MailMessageTest, testReadWriteMultiPartStore);

View File

@ -32,6 +32,7 @@ public:
void testReadWriteMultiPart();
void testReadWriteMultiPartStore();
void testReadDefaultTransferEncoding();
void testReadDefaultContentType();
void testReadQP();
void testRead8Bit();
void testReadMultiPart();