int SpamAssassinClient::ParseFirstBuffer_(std::shared_ptr<ByteBuffer> pBuffer) const { // Don't send first line, since it's the Result header. char *pHeaderEndPosition = StringParser::Search(pBuffer->GetCharBuffer(), pBuffer->GetSize(), "\r\n\r\n"); if (!pHeaderEndPosition) { LOG_DEBUG("The response from SpamAssasin was not valid. Aborting. Expected a header.\r\n"); return -1; } size_t headerLength = pHeaderEndPosition - pBuffer->GetCharBuffer(); AnsiString spamAssassinHeader(pBuffer->GetCharBuffer(), headerLength); std::vector<AnsiString> headerLines = StringParser::SplitString(spamAssassinHeader, "\r\n"); AnsiString firstLine = headerLines[0]; AnsiString secondLine = headerLines[1]; if (firstLine.Compare("SPAMD/1.1 0 EX_OK") != 0) { // We should never get here, since we should always have // a header in the result LOG_DEBUG(Formatter::Format("The response from SpamAssasin was not valid. Aborting. Expected: SPAMD/1.1 0 EX_OK, Got: {0}\r\n", firstLine)); return -1; } if (!secondLine.StartsWith("Content-length:")) { // We should never get here, since we should always have // a header in the result LOG_DEBUG(Formatter::Format("The response from SpamAssasin was not valid. Aborting. Expected: Content-Length:<value>, Got: {0}\r\n", secondLine)); return -1; } // Extract the second line from the first buffer. This buffer // contains the result of the operation (success / failure). std::vector<AnsiString> contentLengthHeader = StringParser::SplitString(secondLine, ":"); if (contentLengthHeader.size() != 2) { LOG_DEBUG(Formatter::Format("The response from SpamAssasin was not valid. Aborting. Content-Length header not properly formatted. Expected: Content-Length:<value>, Got: {0}\r\n", secondLine)); return -1; } int contentLength; std::string sConSize = contentLengthHeader[1].Trim(); if (!StringParser::TryParseInt(sConSize, contentLength)) { LOG_DEBUG(Formatter::Format("The response from SpamAssasin was not valid. Aborting. Content-Length header not properly formatted. Expected: Content-Length:<value>, Got: {0}\r\n", secondLine)); return -1; } // Remove the SA header lines from the result. size_t iEndingBytesSize = pBuffer->GetSize() - headerLength - 4; // 4 due to header ending with \r\n\r\n. pBuffer->Empty(iEndingBytesSize); return contentLength; }