Files
AlarmServer/message.cpp
T

200 lines
5.3 KiB
C++

#include <sstream>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include "outputImage.h"
#include "base64.h"
#include "message.h"
message::message(const std::string& address, const context& context, const std::string& message) :
m_address(address),
m_context(context),
m_mimeBoundary("-_-InvalidBoundary-_-"),
m_contentEncoding("none"),
m_currentImage(0)
{
processMessage(message);
}
std::string Decode(const std::string& data)
{
std::string result;
if (boost::istarts_with(data, "=?utf-8?"))
result = base64_decode(std::string(data.begin() + 10, data.begin() + data.find_last_of('?')));
else
result = base64_decode(data);
return result;
}
void message::processMessage(const std::string& message)
{
try
{
std::cout << "message::processMessage enter" << std::endl;
message::state::type state = message::state::header;
std::string line;
std::istringstream stream(message);
while (std::getline(stream, line, '\r'))
{
boost::erase_all(line, "\n");
switch (state)
{
case state::header:
state = processHeaderLine(line);
break;
case state::data:
state = processDataLine(line);
break;
case state::mimeBoundary:
state = processMimeBoundary(line);
break;
case state::image:
state = processImage(line);
break;
}
}
if (boost::algorithm::contains(m_contentEncoding, "base64"))
{
std::string decoded = Decode(m_subject);
if (decoded.size() > 0)
m_subject = decoded;
}
outputImage image(m_images);
boost::filesystem::path path(m_context.path);
path = boost::filesystem::canonical(path);
path /= m_address;
if (!boost::filesystem::exists(path))
boost::filesystem::create_directory(path);
std::string fileName(getTimeString());
fileName.append(".jpg");
path /= fileName;
image.save(path.string());
if (!m_context.url.empty())
{
std::stringstream url;
url << m_context.url << "?ip=" << m_address << "&file=" << fileName;
m_context.client.GetUrlContents(url.str());
}
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
std::cerr << "Exception: " << e.what() << std::endl;
}
std::cout << "message::processMessage exit" << std::endl;
}
message::state::type message::processHeaderLine(const std::string& line)
{
if (line.empty())
return message::state::data;
if (boost::istarts_with(line, "from:"))
{
m_sender = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::header;
}
if (boost::istarts_with(line, "to:"))
{
m_receiver = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::header;
}
if (boost::istarts_with(line, "subject:"))
{
m_subject = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::header;
}
if (boost::istarts_with(line, "date"))
{
m_date = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::header;
}
if (boost::istarts_with(line, "content-type:"))
{
m_contentType = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::header;
}
if (boost::istarts_with(line, "boundary") || boost::istarts_with(line, "\tboundary") || boost::istarts_with(line, " boundary"))
{
m_mimeBoundary = std::string("--").append(std::string(line.begin() + line.find_first_of('"') + 1, line.begin() + line.find_last_of('"')));
return message::state::header;
}
if (boost::istarts_with(line, "content-transfer-encoding:"))
{
m_contentEncoding = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::header;
}
return message::state::header;
}
message::state::type message::processDataLine(const std::string& line)
{
if (boost::istarts_with(line, m_mimeBoundary))
{
m_contentType = "";
return message::state::mimeBoundary;
}
return message::state::data;
}
message::state::type message::processMimeBoundary(const std::string& line)
{
if (line.empty())
{
if (boost::istarts_with(m_contentType, "image/jpeg") || boost::istarts_with(m_contentType, "image/jpg"))
{
m_mimeImages.push_back(mimeImage(m_imageName));
m_imageName = "";
return message::state::image;
}
return message::state::data;
}
if (boost::istarts_with(line, "content-type:"))
{
m_contentType = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::mimeBoundary;
}
if (boost::istarts_with(line, "name") || boost::istarts_with(line, "\tname"))
{
m_imageName = "image.jpg";
//m_imageName = Decode(std::string(line.begin() + line.find_first_of('"') + 1, line.begin() + line.find_last_of('"')));
return message::state::mimeBoundary;
}
if (boost::istarts_with(line, "content-transfer-encoding:"))
{
m_contentEncoding = std::string(line.begin() + line.find_first_of(' ') + 1, line.end());
return message::state::mimeBoundary;
}
return message::state::mimeBoundary;
}
message::state::type message::processImage(const std::string& line)
{
if (boost::istarts_with(line, m_mimeBoundary))
{
m_images.push_back(m_mimeImages[m_currentImage].decodeImageData());
++m_currentImage;
m_contentType = "";
return message::state::mimeBoundary;
}
m_mimeImages[m_currentImage].appendData(line);
return message::state::image;
}