Fixed multi-line terminator spanning on multiple incoming packets.
This commit is contained in:
parent
fbfa4f0b86
commit
090c817611
@ -24,6 +24,7 @@
|
|||||||
#include "vmime/platformDependant.hpp"
|
#include "vmime/platformDependant.hpp"
|
||||||
#include "vmime/messageId.hpp"
|
#include "vmime/messageId.hpp"
|
||||||
#include "vmime/utility/md5.hpp"
|
#include "vmime/utility/md5.hpp"
|
||||||
|
#include "vmime/utility/filteredStream.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -412,7 +413,6 @@ void POP3Store::readResponse(string& buffer, const bool multiLine,
|
|||||||
void POP3Store::readResponse(utility::outputStream& os,
|
void POP3Store::readResponse(utility::outputStream& os,
|
||||||
utility::progressionListener* progress, const int predictedSize)
|
utility::progressionListener* progress, const int predictedSize)
|
||||||
{
|
{
|
||||||
bool foundTerminator = false;
|
|
||||||
int current = 0, total = predictedSize;
|
int current = 0, total = predictedSize;
|
||||||
|
|
||||||
string temp;
|
string temp;
|
||||||
@ -424,9 +424,14 @@ void POP3Store::readResponse(utility::outputStream& os,
|
|||||||
if (m_timeoutHandler)
|
if (m_timeoutHandler)
|
||||||
m_timeoutHandler->resetTimeOut();
|
m_timeoutHandler->resetTimeOut();
|
||||||
|
|
||||||
string::value_type last1 = '\0', last2 = '\0';
|
utility::inputStreamSocketAdapter sis(*m_socket);
|
||||||
|
utility::stopSequenceFilteredInputStream <5> sfis1(sis, "\r\n.\r\n");
|
||||||
|
utility::stopSequenceFilteredInputStream <3> sfis2(sfis1, "\n.\n");
|
||||||
|
utility::dotFilteredInputStream dfis(sfis2); // "\n.." --> "\n."
|
||||||
|
|
||||||
for ( ; !foundTerminator ; )
|
utility::inputStream& is = dfis;
|
||||||
|
|
||||||
|
while (!is.eof())
|
||||||
{
|
{
|
||||||
#if 0 // not supported
|
#if 0 // not supported
|
||||||
// Check for possible cancellation
|
// Check for possible cancellation
|
||||||
@ -442,10 +447,10 @@ void POP3Store::readResponse(utility::outputStream& os,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Receive data from the socket
|
// Receive data from the socket
|
||||||
string receiveBuffer;
|
utility::stream::value_type buffer[65536];
|
||||||
m_socket->receive(receiveBuffer);
|
const utility::stream::size_type read = is.read(buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (receiveBuffer.empty()) // buffer is empty
|
if (read == 0) // buffer is empty
|
||||||
{
|
{
|
||||||
platformDependant::getHandler()->wait();
|
platformDependant::getHandler()->wait();
|
||||||
continue;
|
continue;
|
||||||
@ -455,32 +460,10 @@ void POP3Store::readResponse(utility::outputStream& os,
|
|||||||
if (m_timeoutHandler)
|
if (m_timeoutHandler)
|
||||||
m_timeoutHandler->resetTimeOut();
|
m_timeoutHandler->resetTimeOut();
|
||||||
|
|
||||||
// Check for transparent characters: '\n..' becomes '\n.'
|
|
||||||
const string::value_type first = receiveBuffer[0];
|
|
||||||
|
|
||||||
if (first == '.' && last2 == '\n' && last1 == '.')
|
|
||||||
{
|
|
||||||
receiveBuffer.erase(receiveBuffer.begin());
|
|
||||||
}
|
|
||||||
else if (receiveBuffer.length() >= 2 && first == '.' &&
|
|
||||||
receiveBuffer[1] == '.' && last1 == '\n')
|
|
||||||
{
|
|
||||||
receiveBuffer.erase(receiveBuffer.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (string::size_type trans ;
|
|
||||||
string::npos != (trans = receiveBuffer.find("\n..")) ; )
|
|
||||||
{
|
|
||||||
receiveBuffer.replace(trans, 3, "\n.");
|
|
||||||
}
|
|
||||||
|
|
||||||
last1 = receiveBuffer[receiveBuffer.length() - 1];
|
|
||||||
last2 = (receiveBuffer.length() >= 2) ? receiveBuffer[receiveBuffer.length() - 2] : 0;
|
|
||||||
|
|
||||||
// If we don't have extracted the response code yet
|
// If we don't have extracted the response code yet
|
||||||
if (!codeDone)
|
if (!codeDone)
|
||||||
{
|
{
|
||||||
temp += receiveBuffer;
|
temp += string(buffer, read);
|
||||||
|
|
||||||
string firstLine;
|
string firstLine;
|
||||||
|
|
||||||
@ -489,21 +472,19 @@ void POP3Store::readResponse(utility::outputStream& os,
|
|||||||
if (!isSuccessResponse(firstLine))
|
if (!isSuccessResponse(firstLine))
|
||||||
throw exceptions::command_error("?", firstLine);
|
throw exceptions::command_error("?", firstLine);
|
||||||
|
|
||||||
receiveBuffer = temp;
|
codeDone = true;
|
||||||
|
|
||||||
|
os.write(temp.data(), temp.length());
|
||||||
temp.clear();
|
temp.clear();
|
||||||
|
|
||||||
codeDone = true;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (codeDone)
|
|
||||||
{
|
{
|
||||||
// Check for terminator string (and strip it if present)
|
|
||||||
foundTerminator = checkTerminator(receiveBuffer, true);
|
|
||||||
|
|
||||||
// Inject the data into the output stream
|
// Inject the data into the output stream
|
||||||
os.write(receiveBuffer.data(), receiveBuffer.length());
|
os.write(buffer, read);
|
||||||
current += receiveBuffer.length();
|
current += read;
|
||||||
|
|
||||||
// Notify progression
|
// Notify progression
|
||||||
if (progress)
|
if (progress)
|
||||||
@ -649,3 +630,4 @@ const std::vector <serviceInfos::property> POP3Store::_infos::getAvailableProper
|
|||||||
} // pop3
|
} // pop3
|
||||||
} // messaging
|
} // messaging
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user