#include #include #include #include #include #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) { 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()); } } 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; }