Esempio n. 1
0
void POP3ClientSessionTest::testRetrieveHeader()
{
	DialogServer server;
	server.addResponse("+OK POP3 Ready...");
	server.addResponse("+OK USER");
	server.addResponse("+OK PASS");
	server.addResponse(
		"+OK Here comes the message\r\n"
		"From: [email protected]\r\n"
		"To: [email protected]\r\n"
		"Subject: test\r\n"
		"\r\n"
		"."
	);
	server.addResponse("+OK QUIT");
	POP3ClientSession session("localhost", server.port());
	session.login("user", "secret");
	server.clearCommands();
	MessageHeader header;
	session.retrieveHeader(1, header);
	std::string cmd = server.popCommand();
	assert (cmd == "TOP 1 0");
	assert (header.get("From") == "*****@*****.**");
	assert (header.get("To") == "*****@*****.**");
	assert (header.get("Subject") == "test");
	session.close();
}
Esempio n. 2
0
void MailMessage::readPart(std::istream& istr, const MessageHeader& header, PartHandler& handler)
{
	std::string encoding;
	if (header.has(HEADER_CONTENT_TRANSFER_ENCODING))
	{
		encoding = header.get(HEADER_CONTENT_TRANSFER_ENCODING);
		// get rid of a parameter if one is set
		std::string::size_type pos = encoding.find(';');
		if (pos != std::string::npos)
			encoding.resize(pos);
	}
	if (icompare(encoding, CTE_QUOTED_PRINTABLE) == 0)
	{
		QuotedPrintableDecoder decoder(istr);
		handlePart(decoder, header, handler);
	}
	else if (icompare(encoding, CTE_BASE64) == 0)
	{
		Base64Decoder decoder(istr);
		handlePart(decoder, header, handler);
	}
	else
	{
		handlePart(istr, header, handler);
	}
}
Esempio n. 3
0
	void handlePart(const MessageHeader& header, std::istream& stream)
	{
		_type = header.get("Content-Type", "(unspecified)");
		if (header.has("Content-Disposition"))
		{
			std::string disp;
			NameValueCollection params;
			MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
			_name = params.get("name", "(unnamed)");
			_fileName = params.get("filename", "(unnamed)");
		}
		
		CountingInputStream istr(stream);
		NullOutputStream ostr;
		StreamCopier::copyStream(istr, ostr);
		_length = istr.chars();
	}
Esempio n. 4
0
void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler)
{
	static const int eof = std::char_traits<char>::eof();

	int fields = 0;
	MultipartReader reader(istr, _boundary);
	while (reader.hasNextPart())
	{
		if (_fieldLimit > 0 && fields == _fieldLimit)
			throw HTMLFormException("Too many form fields");
		MessageHeader header;
		reader.nextPart(header);
		std::string disp;
		NameValueCollection params;
		if (header.has("Content-Disposition"))
		{
			std::string cd = header.get("Content-Disposition");
			MessageHeader::splitParameters(cd, disp, params);
		}
		if (params.has("filename"))
		{
			handler.handlePart(header, reader.stream());
			// Ensure that the complete part has been read.
			while (reader.stream().good()) reader.stream().get();
		}
		else
		{
			std::string name = params["name"];
			std::string value;
			std::istream& istr = reader.stream();
			int ch = istr.get();
			while (ch != eof)
			{
				value += (char) ch;
				ch = istr.get();
			}
			add(name, value);
		}
		++fields;
	}
}
Esempio n. 5
0
void MyPartHandler::handlePart(const MessageHeader& messageHeader, std::istream& stream)
{
    stringstream headerSS;
    messageHeader.write(headerSS);
    _headers.push_back(headerSS.str());

    string contentType = messageHeader.get("Content-Type", "nil");

    if((MyString::ToLower(contentType)).find("multipart") == 0) {
        MultipartReader multipartReader(stream);

        while(multipartReader.hasNextPart()) {
            MessageHeader subMessageHeader;
            multipartReader.nextPart(subMessageHeader);

            string subContentType = subMessageHeader.get("Content-Type", "nil");
            // Convert to lower case for comparison only
            string lc_subctype = MyString::ToLower(subContentType);

            //Priority is text/plain format, else save text/html format
            if(lc_subctype == "nil") {
                continue;
            } else if(lc_subctype.find("application") != string::npos && lc_subctype.find("name") != string::npos) {
                // Save attachment(s) in sub-content part
                string disp;
                string filename;
                string attachment;
                NameValueCollection params;

                MessageHeader::splitParameters(lc_subctype, disp, params);
                filename = params.get("name", "nil");
                if(filename != "nil") {
                    // Filename and Attachments might be encoded in Base64 or QuotedPrintable
                    _filenames.push_back(DecodeString(filename));
                    string encoder = MyString::ToLower(subMessageHeader.get("Content-Transfer-Encoding", "nil"));
                    if(encoder == "base64") {
                        Poco::Base64Decoder base64Decoder(multipartReader.stream());
                        StreamCopier::copyToString(base64Decoder, attachment);
                    } else if(encoder == "quoted-printable") {
                        Poco::Net::QuotedPrintableDecoder qpDecoder(multipartReader.stream());
                        StreamCopier::copyToString(qpDecoder, attachment);
                    } else {
                        StreamCopier::copyToString(multipartReader.stream(), attachment);
                    }

                    if (!attachment.empty()) {
                        _attachments.push_back(attachment);
                    }
                }
            } else if(lc_subctype.find("boundary") != string::npos) {
                int bStart = 0;
                if(_myboundary.empty()) {
                    bStart = subContentType.find('_');
                    _myboundary = MyString::FixField(subContentType, bStart, (subContentType.length() - (bStart + 1)));
                }
            } else if(lc_subctype.find("text/plain") == 0) {
                string charset;

                if(subContentType.find("charset") != string::npos) {
                    //Outlook: Content-Type text/plain charset="us-ascii"
                    //Yahoo: Content-Type text/plain charset=iso-8859-1
                    string subct_clean = MyString::RemoveChar(subContentType, '"');
                    int charpos = subct_clean.find("charset=") + 8; //+8 to bypass the word "charset="
                    charset = MyString::FixField(subct_clean, charpos, (subContentType.length() - charpos) );
                }

                //If body variable is not empty, it has the text/plain format of the email body.
                string cte = subMessageHeader.get("Content-Transfer-Encoding", "nil");
                //For some reasons, emails from outlook (content transfer encoding is specified as quoted-printable in header), it generates nil result in QuotedPrintableDecoder
                if(charset.compare("us-ascii") != 0) {
                    if(cte == "base64")	{
                        Poco::Base64Decoder base64Decoder(multipartReader.stream());
                        StreamCopier::copyToString(base64Decoder, _body);
                    } else if(cte == "quoted-printable") {
                        Poco::Net::QuotedPrintableDecoder qpDecoder(multipartReader.stream());
                        StreamCopier::copyToString(qpDecoder, _body);
                    } else {
                        StreamCopier::copyToString(multipartReader.stream(), _body);
                    }
                } else {
                    StreamCopier::copyToString(multipartReader.stream(), _body);
                }

                if(!_myboundary.empty() && _myboundary.compare(multipartReader.boundary()) != 0) {
                    _body = MyString::Trim(MyString::FixField(_body, 0, (_body.find(_myboundary) - 2))); //-2 for the boundary heading, e.g. --_000_OD67Eexchau_
                }
            } else {
                if(_body.empty() || _body.length() > 0) break;
                // Will hit error "Malformed message: Field value too long/no CRLF found" under MesssageHeader.read() in MessageHeader.cpp
                // if "continue" is used.  "text/plain" part will always come before "text/html" part
                //Keep this code for reference of retrieving text/html content, ignore text/html part at this moment
                /*
                  else if(subContentType.find("text/html") == 0) {
                    string cte = subMessageHeader.get("Content-Transfer-Encoding", "nil");
                    if(cte == "base64") {
                      Poco::Base64Decoder base64Decoder(multipartReader.stream());
                      StreamCopier::copyToString(base64Decoder, _body);
                    } else if(cte == "quoted-printable") {
                  Poco::Net::QuotedPrintableDecoder qpDecoder(multipartReader.stream());
                  StreamCopier::copyToString(qpDecoder, _body);
                    } else
                  StreamCopier::copyToString(stream, _body);
                */
            }
        }
    } else {
        //Email body content
        //Change request 20101007: Ignore text/html part
        if(contentType.find("text/html") == string::npos && (_body.empty() || _body.length() > 0))
            StreamCopier::copyToString(stream, _body);
    }

}