IMAP commands.
This commit is contained in:
parent
86788ce022
commit
9d73fc5382
410
src/vmime/net/imap/IMAPCommand.cpp
Normal file
410
src/vmime/net/imap/IMAPCommand.cpp
Normal file
@ -0,0 +1,410 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2014 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
|
||||
|
||||
|
||||
#include "vmime/net/imap/IMAPCommand.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPUtils.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
IMAPCommand::IMAPCommand(const string& text, const string& traceText)
|
||||
: m_text(text), m_traceText(traceText)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::LOGIN(const string& username, const string& password)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "LOGIN " << IMAPUtils::quoteString(username)
|
||||
<< " " << IMAPUtils::quoteString(password);
|
||||
|
||||
std::ostringstream trace;
|
||||
trace.imbue(std::locale::classic());
|
||||
trace << "LOGIN <username> <password>";
|
||||
|
||||
return createCommand(cmd.str(), trace.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::AUTHENTICATE(const string& mechName)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "AUTHENTICATE " << mechName;
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::AUTHENTICATE(const string& mechName, const string& initialResponse)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "AUTHENTICATE " << mechName << " " << initialResponse;
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::LIST(const string& refName, const string& mailboxName)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "LIST " << IMAPUtils::quoteString(refName)
|
||||
<< " " << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::SELECT
|
||||
(const bool readOnly, const string& mailboxName, const std::vector <string>& params)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
|
||||
if (readOnly)
|
||||
cmd << "EXAMINE ";
|
||||
else
|
||||
cmd << "SELECT ";
|
||||
|
||||
cmd << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
if (!params.empty())
|
||||
{
|
||||
cmd << " (";
|
||||
|
||||
for (size_t i = 0, n = params.size() ; i < n ; ++i)
|
||||
{
|
||||
if (i != 0) cmd << " ";
|
||||
cmd << params[i];
|
||||
}
|
||||
|
||||
cmd << ")";
|
||||
}
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::STATUS
|
||||
(const string& mailboxName, const std::vector <string>& attribs)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "STATUS " << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
cmd << " (";
|
||||
|
||||
for (size_t i = 0, n = attribs.size() ; i < n ; ++i)
|
||||
{
|
||||
if (i != 0) cmd << " ";
|
||||
cmd << attribs[i];
|
||||
}
|
||||
|
||||
cmd << ")";
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::CREATE
|
||||
(const string& mailboxName, const std::vector <string>& params)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "CREATE " << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
if (!params.empty())
|
||||
{
|
||||
cmd << " (";
|
||||
|
||||
for (size_t i = 0, n = params.size() ; i < n ; ++i)
|
||||
{
|
||||
if (i != 0) cmd << " ";
|
||||
cmd << params[i];
|
||||
}
|
||||
|
||||
cmd << ")";
|
||||
}
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::DELETE(const string& mailboxName)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "DELETE " << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::RENAME
|
||||
(const string& mailboxName, const string& newMailboxName)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "RENAME " << IMAPUtils::quoteString(mailboxName)
|
||||
<< " " << IMAPUtils::quoteString(newMailboxName);
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::FETCH
|
||||
(const messageSet& msgs, const std::vector <string>& params)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
|
||||
if (msgs.isUIDSet())
|
||||
cmd << "UID FETCH " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
else
|
||||
cmd << "FETCH " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
|
||||
if (params.size() == 1)
|
||||
{
|
||||
cmd << " " << params[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd << " (";
|
||||
|
||||
for (size_t i = 0, n = params.size() ; i < n ; ++i)
|
||||
{
|
||||
if (i != 0) cmd << " ";
|
||||
cmd << params[i];
|
||||
}
|
||||
|
||||
cmd << ")";
|
||||
}
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::STORE
|
||||
(const messageSet& msgs, const int mode, const std::vector <string>& flags)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
|
||||
if (msgs.isUIDSet())
|
||||
cmd << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
else
|
||||
cmd << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
|
||||
if (mode == message::FLAG_MODE_ADD)
|
||||
cmd << " +FLAGS ";
|
||||
else if (mode == message::FLAG_MODE_REMOVE)
|
||||
cmd << " -FLAGS ";
|
||||
else // if (mode == message::FLAG_MODE_SET)
|
||||
cmd << " FLAGS ";
|
||||
|
||||
cmd << "(";
|
||||
|
||||
for (size_t i = 0, n = flags.size() ; i < n ; ++i)
|
||||
{
|
||||
if (i != 0) cmd << " ";
|
||||
cmd << flags[i];
|
||||
}
|
||||
|
||||
cmd << ")";
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::APPEND
|
||||
(const string& mailboxName, const std::vector <string>& flags,
|
||||
vmime::datetime* date, const size_t size)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "APPEND " << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
if (!flags.empty())
|
||||
{
|
||||
cmd << " (";
|
||||
|
||||
for (size_t i = 0, n = flags.size() ; i < n ; ++i)
|
||||
{
|
||||
if (i != 0) cmd << " ";
|
||||
cmd << flags[i];
|
||||
}
|
||||
|
||||
cmd << ")";
|
||||
}
|
||||
|
||||
if (date != NULL)
|
||||
cmd << " " << IMAPUtils::dateTime(*date);
|
||||
|
||||
cmd << " {" << size << "}";
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::COPY
|
||||
(const messageSet& msgs, const string& mailboxName)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
|
||||
if (msgs.isUIDSet())
|
||||
cmd << "UID COPY " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
else
|
||||
cmd << "COPY " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
|
||||
cmd << " " << IMAPUtils::quoteString(mailboxName);
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::SEARCH
|
||||
(const std::vector <string>& keys, const vmime::charset* charset)
|
||||
{
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
cmd << "SEARCH";
|
||||
|
||||
if (charset)
|
||||
cmd << " CHARSET " << charset->getName();
|
||||
|
||||
for (size_t i = 0, n = keys.size() ; i < n ; ++i)
|
||||
cmd << " " << keys[i];
|
||||
|
||||
return createCommand(cmd.str());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::STARTTLS()
|
||||
{
|
||||
return createCommand("STARTTLS");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::CAPABILITY()
|
||||
{
|
||||
return createCommand("CAPABILITY");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::NOOP()
|
||||
{
|
||||
return createCommand("NOOP");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::EXPUNGE()
|
||||
{
|
||||
return createCommand("EXPUNGE");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::CLOSE()
|
||||
{
|
||||
return createCommand("CLOSE");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::LOGOUT()
|
||||
{
|
||||
return createCommand("LOGOUT");
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
shared_ptr <IMAPCommand> IMAPCommand::createCommand
|
||||
(const string& text, const string& traceText)
|
||||
{
|
||||
if (traceText.empty())
|
||||
return shared_ptr <IMAPCommand>(new IMAPCommand(text, text));
|
||||
else
|
||||
return shared_ptr <IMAPCommand>(new IMAPCommand(text, traceText));
|
||||
}
|
||||
|
||||
|
||||
const string IMAPCommand::getText() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
|
||||
const string IMAPCommand::getTraceText() const
|
||||
{
|
||||
return m_traceText;
|
||||
}
|
||||
|
||||
|
||||
void IMAPCommand::send(shared_ptr <IMAPConnection> conn)
|
||||
{
|
||||
conn->sendCommand(dynamicCast <IMAPCommand>(shared_from_this()));
|
||||
}
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
|
124
src/vmime/net/imap/IMAPCommand.hpp
Normal file
124
src/vmime/net/imap/IMAPCommand.hpp
Normal file
@ -0,0 +1,124 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2014 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_NET_IMAP_IMAPCOMMAND_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPCOMMAND_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
|
||||
|
||||
|
||||
#include "vmime/object.hpp"
|
||||
#include "vmime/base.hpp"
|
||||
#include "vmime/datetime.hpp"
|
||||
|
||||
#include "vmime/net/messageSet.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
class IMAPConnection;
|
||||
|
||||
|
||||
/** An IMAP command that will be sent to the server.
|
||||
*/
|
||||
class VMIME_EXPORT IMAPCommand : public object
|
||||
{
|
||||
public:
|
||||
|
||||
static shared_ptr <IMAPCommand> LOGIN(const string& username, const string& password);
|
||||
static shared_ptr <IMAPCommand> AUTHENTICATE(const string& mechName);
|
||||
static shared_ptr <IMAPCommand> AUTHENTICATE(const string& mechName, const string& initialResponse);
|
||||
static shared_ptr <IMAPCommand> LIST(const string& refName, const string& mailboxName);
|
||||
static shared_ptr <IMAPCommand> SELECT(const bool readOnly, const string& mailboxName, const std::vector <string>& params);
|
||||
static shared_ptr <IMAPCommand> STATUS(const string& mailboxName, const std::vector <string>& attribs);
|
||||
static shared_ptr <IMAPCommand> CREATE(const string& mailboxName, const std::vector <string>& params);
|
||||
static shared_ptr <IMAPCommand> DELETE(const string& mailboxName);
|
||||
static shared_ptr <IMAPCommand> RENAME(const string& mailboxName, const string& newMailboxName);
|
||||
static shared_ptr <IMAPCommand> FETCH(const messageSet& msgs, const std::vector <string>& params);
|
||||
static shared_ptr <IMAPCommand> STORE(const messageSet& msgs, const int mode, const std::vector <string>& flags);
|
||||
static shared_ptr <IMAPCommand> APPEND(const string& mailboxName, const std::vector <string>& flags, vmime::datetime* date, const size_t size);
|
||||
static shared_ptr <IMAPCommand> COPY(const messageSet& msgs, const string& mailboxName);
|
||||
static shared_ptr <IMAPCommand> SEARCH(const std::vector <string>& keys, const vmime::charset* charset);
|
||||
static shared_ptr <IMAPCommand> STARTTLS();
|
||||
static shared_ptr <IMAPCommand> CAPABILITY();
|
||||
static shared_ptr <IMAPCommand> NOOP();
|
||||
static shared_ptr <IMAPCommand> EXPUNGE();
|
||||
static shared_ptr <IMAPCommand> CLOSE();
|
||||
static shared_ptr <IMAPCommand> LOGOUT();
|
||||
|
||||
/** Creates a new IMAP command with the specified text.
|
||||
*
|
||||
* @param text command text
|
||||
* @param traceText trace text (if empty, command text is used)
|
||||
* @return a new IMAPCommand object
|
||||
*/
|
||||
static shared_ptr <IMAPCommand> createCommand(const string& text, const string& traceText = "");
|
||||
|
||||
/** Sends this command over the specified connection.
|
||||
*
|
||||
* @param conn connection onto which the command will be sent
|
||||
*/
|
||||
virtual void send(shared_ptr <IMAPConnection> conn);
|
||||
|
||||
/** Returns the full text of the command, including command name
|
||||
* and parameters (if any). This is the text that will be sent
|
||||
* to the server.
|
||||
*
|
||||
* @return command text (eg. "LOGIN myusername mypassword")
|
||||
*/
|
||||
virtual const string getText() const;
|
||||
|
||||
/** Returns the full text of the command, suitable for outputing
|
||||
* to the tracer.
|
||||
*
|
||||
* @return trace text (eg. "LOGIN myusername ***")
|
||||
*/
|
||||
virtual const string getTraceText() const;
|
||||
|
||||
protected:
|
||||
|
||||
IMAPCommand(const string& text, const string& traceText);
|
||||
IMAPCommand(const IMAPCommand&);
|
||||
|
||||
private:
|
||||
|
||||
string m_text;
|
||||
string m_traceText;
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPCOMMAND_HPP_INCLUDED
|
@ -31,6 +31,7 @@
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPUtils.hpp"
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
#include "vmime/net/imap/IMAPCommand.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/platform.hpp"
|
||||
@ -70,6 +71,7 @@ IMAPConnection::IMAPConnection(shared_ptr <IMAPStore> store, shared_ptr <securit
|
||||
m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(null),
|
||||
m_secured(false), m_firstTag(true), m_capabilitiesFetched(false), m_noModSeq(false)
|
||||
{
|
||||
m_tag = make_shared <IMAPTag>();
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +135,6 @@ void IMAPConnection::connect()
|
||||
m_socket->connect(address, port);
|
||||
|
||||
|
||||
m_tag = make_shared <IMAPTag>();
|
||||
m_parser = make_shared <IMAPParser>(m_tag, m_socket, m_timeoutHandler);
|
||||
|
||||
|
||||
@ -259,8 +260,8 @@ void IMAPConnection::authenticate()
|
||||
const string username = getAuthenticator()->getUsername();
|
||||
const string password = getAuthenticator()->getPassword();
|
||||
|
||||
send(true, "LOGIN " + IMAPUtils::quoteString(username)
|
||||
+ " " + IMAPUtils::quoteString(password), true);
|
||||
shared_ptr <IMAPConnection> conn = dynamicCast <IMAPConnection>(shared_from_this());
|
||||
IMAPCommand::LOGIN(username, password)->send(conn);
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
||||
|
||||
@ -355,8 +356,7 @@ void IMAPConnection::authenticateSASL()
|
||||
|
||||
saslSession->init();
|
||||
|
||||
std::ostringstream cmd;
|
||||
cmd << "AUTHENTICATE " << mech->getName();
|
||||
shared_ptr <IMAPCommand> authCmd;
|
||||
|
||||
if (saslSession->getMechanism()->hasInitialResponse())
|
||||
{
|
||||
@ -369,12 +369,16 @@ void IMAPConnection::authenticateSASL()
|
||||
delete [] initialResp;
|
||||
|
||||
if (encodedInitialResp.empty())
|
||||
cmd << " =";
|
||||
authCmd = IMAPCommand::AUTHENTICATE(mech->getName(), "=");
|
||||
else
|
||||
cmd << " " << encodedInitialResp;
|
||||
authCmd = IMAPCommand::AUTHENTICATE(mech->getName(), encodedInitialResp);
|
||||
}
|
||||
else
|
||||
{
|
||||
authCmd = IMAPCommand::AUTHENTICATE(mech->getName());
|
||||
}
|
||||
|
||||
send(true, cmd.str(), true);
|
||||
authCmd->send(dynamicCast <IMAPConnection>(shared_from_this()));
|
||||
|
||||
for (bool cont = true ; cont ; )
|
||||
{
|
||||
@ -428,7 +432,8 @@ void IMAPConnection::authenticateSASL()
|
||||
(challenge, challengeLen, &resp, &respLen);
|
||||
|
||||
// Send response
|
||||
send(false, saslContext->encodeB64(resp, respLen), true);
|
||||
const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n";
|
||||
sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length());
|
||||
|
||||
// Server capabilities may change when logged in
|
||||
invalidateCapabilities();
|
||||
@ -448,7 +453,7 @@ void IMAPConnection::authenticateSASL()
|
||||
}
|
||||
|
||||
// Cancel SASL exchange
|
||||
send(false, "*", true);
|
||||
sendRaw(utility::stringUtils::bytesFromString("*\r\n"), 3);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -483,7 +488,7 @@ void IMAPConnection::startTLS()
|
||||
{
|
||||
try
|
||||
{
|
||||
send(true, "STARTTLS", true);
|
||||
IMAPCommand::STARTTLS()->send(dynamicCast <IMAPConnection>(shared_from_this()));
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
||||
|
||||
@ -582,7 +587,7 @@ void IMAPConnection::invalidateCapabilities()
|
||||
|
||||
void IMAPConnection::fetchCapabilities()
|
||||
{
|
||||
send(true, "CAPABILITY", true);
|
||||
IMAPCommand::CAPABILITY()->send(dynamicCast <IMAPConnection>(shared_from_this()));
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
||||
|
||||
@ -675,7 +680,7 @@ void IMAPConnection::internalDisconnect()
|
||||
{
|
||||
if (isConnected())
|
||||
{
|
||||
send(true, "LOGOUT", true);
|
||||
IMAPCommand::LOGOUT()->send(dynamicCast <IMAPConnection>(shared_from_this()));
|
||||
|
||||
m_socket->disconnect();
|
||||
m_socket = null;
|
||||
@ -692,7 +697,7 @@ void IMAPConnection::internalDisconnect()
|
||||
|
||||
void IMAPConnection::initHierarchySeparator()
|
||||
{
|
||||
send(true, "LIST \"\" \"\"", true);
|
||||
IMAPCommand::LIST("", "")->send(dynamicCast <IMAPConnection>(shared_from_this()));
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
||||
|
||||
@ -732,42 +737,16 @@ void IMAPConnection::initHierarchySeparator()
|
||||
}
|
||||
|
||||
|
||||
void IMAPConnection::send(bool tag, const string& what, bool end)
|
||||
void IMAPConnection::sendCommand(shared_ptr <IMAPCommand> cmd)
|
||||
{
|
||||
if (tag && !m_firstTag)
|
||||
if (!m_firstTag)
|
||||
++(*m_tag);
|
||||
|
||||
#if VMIME_DEBUG
|
||||
std::ostringstream oss;
|
||||
|
||||
if (tag)
|
||||
{
|
||||
oss << string(*m_tag);
|
||||
oss << " ";
|
||||
}
|
||||
|
||||
oss << what;
|
||||
|
||||
if (end)
|
||||
oss << "\r\n";
|
||||
|
||||
m_socket->send(oss.str());
|
||||
#else
|
||||
if (tag)
|
||||
{
|
||||
m_socket->send(*m_tag);
|
||||
m_socket->send(" ");
|
||||
}
|
||||
|
||||
m_socket->send(what);
|
||||
|
||||
if (end)
|
||||
{
|
||||
m_socket->send(cmd->getText());
|
||||
m_socket->send("\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tag)
|
||||
m_firstTag = false;
|
||||
}
|
||||
|
||||
@ -826,6 +805,18 @@ shared_ptr <const socket> IMAPConnection::getSocket() const
|
||||
}
|
||||
|
||||
|
||||
void IMAPConnection::setSocket(shared_ptr <socket> sok)
|
||||
{
|
||||
m_socket = sok;
|
||||
}
|
||||
|
||||
|
||||
shared_ptr <IMAPTag> IMAPConnection::getTag()
|
||||
{
|
||||
return m_tag;
|
||||
}
|
||||
|
||||
|
||||
bool IMAPConnection::isMODSEQDisabled() const
|
||||
{
|
||||
return m_noModSeq;
|
||||
|
@ -48,6 +48,7 @@ namespace imap {
|
||||
|
||||
class IMAPTag;
|
||||
class IMAPStore;
|
||||
class IMAPCommand;
|
||||
|
||||
|
||||
class VMIME_EXPORT IMAPConnection : public object
|
||||
@ -79,7 +80,7 @@ public:
|
||||
char hierarchySeparator() const;
|
||||
|
||||
|
||||
void send(bool tag, const string& what, bool end);
|
||||
void sendCommand(shared_ptr <IMAPCommand> cmd);
|
||||
void sendRaw(const byte_t* buffer, const size_t count);
|
||||
|
||||
IMAPParser::response* readResponse(IMAPParser::literalHandler* lh = NULL);
|
||||
@ -102,6 +103,9 @@ public:
|
||||
shared_ptr <connectionInfos> getConnectionInfos() const;
|
||||
|
||||
shared_ptr <const socket> getSocket() const;
|
||||
void setSocket(shared_ptr <socket> sok);
|
||||
|
||||
shared_ptr <IMAPTag> getTag();
|
||||
|
||||
bool isMODSEQDisabled() const;
|
||||
void disableMODSEQ();
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "vmime/net/imap/IMAPUtils.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPFolderStatus.hpp"
|
||||
#include "vmime/net/imap/IMAPCommand.hpp"
|
||||
|
||||
#include "vmime/message.hpp"
|
||||
|
||||
@ -157,20 +158,16 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable)
|
||||
// S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
|
||||
// S: A142 OK [READ-WRITE] SELECT completed
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
if (mode == MODE_READ_ONLY)
|
||||
oss << "EXAMINE ";
|
||||
else
|
||||
oss << "SELECT ";
|
||||
|
||||
oss << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(connection->hierarchySeparator(), getFullPath()));
|
||||
std::vector <string> selectParams;
|
||||
|
||||
if (m_connection->hasCapability("CONDSTORE"))
|
||||
oss << " (CONDSTORE)";
|
||||
selectParams.push_back("CONDSTORE");
|
||||
|
||||
connection->send(true, oss.str(), true);
|
||||
IMAPCommand::SELECT(
|
||||
mode == MODE_READ_ONLY,
|
||||
IMAPUtils::pathToString(connection->hierarchySeparator(), getFullPath()),
|
||||
selectParams
|
||||
)->send(connection);
|
||||
|
||||
// Read the response
|
||||
std::auto_ptr <IMAPParser::response> resp(connection->readResponse());
|
||||
@ -289,7 +286,7 @@ void IMAPFolder::close(const bool expunge)
|
||||
if (m_mode == MODE_READ_ONLY)
|
||||
throw exceptions::operation_not_supported();
|
||||
|
||||
oldConnection->send(true, "CLOSE", true);
|
||||
IMAPCommand::CLOSE()->send(oldConnection);
|
||||
}
|
||||
|
||||
// Close this folder connection
|
||||
@ -345,8 +342,7 @@ void IMAPFolder::create(const folderAttributes& attribs)
|
||||
if (attribs.getType() & folderAttributes::TYPE_CONTAINS_FOLDERS)
|
||||
mailbox += m_connection->hierarchySeparator();
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "CREATE " << IMAPUtils::quoteString(mailbox);
|
||||
std::vector <string> createParams;
|
||||
|
||||
if (attribs.getSpecialUse() != folderAttributes::SPECIALUSE_NONE)
|
||||
{
|
||||
@ -354,7 +350,8 @@ void IMAPFolder::create(const folderAttributes& attribs)
|
||||
throw exceptions::operation_not_supported();
|
||||
|
||||
// C: t2 CREATE MySpecial (USE (\Drafts \Sent))
|
||||
oss << "(USE (";
|
||||
std::ostringstream oss;
|
||||
oss << "USE (";
|
||||
|
||||
switch (attribs.getSpecialUse())
|
||||
{
|
||||
@ -369,10 +366,12 @@ void IMAPFolder::create(const folderAttributes& attribs)
|
||||
case folderAttributes::SPECIALUSE_IMPORTANT: oss << "\\Important"; break;
|
||||
}
|
||||
|
||||
oss << "))";
|
||||
oss << ")";
|
||||
|
||||
createParams.push_back(oss.str());
|
||||
}
|
||||
|
||||
m_connection->send(true, oss.str(), true);
|
||||
IMAPCommand::CREATE(mailbox, createParams)->send(m_connection);
|
||||
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -407,10 +406,7 @@ void IMAPFolder::destroy()
|
||||
const string mailbox = IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath());
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "DELETE " << IMAPUtils::quoteString(mailbox);
|
||||
|
||||
m_connection->send(true, oss.str(), true);
|
||||
IMAPCommand::DELETE(mailbox)->send(m_connection);
|
||||
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -464,12 +460,8 @@ int IMAPFolder::testExistAndGetType()
|
||||
//
|
||||
// ==> NO, does not exist
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "LIST \"\" ";
|
||||
oss << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath()));
|
||||
|
||||
m_connection->send(true, oss.str(), true);
|
||||
IMAPCommand::LIST("", IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath()))->send(m_connection);
|
||||
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -560,14 +552,10 @@ std::vector <shared_ptr <message> > IMAPFolder::getMessages(const messageSet& ms
|
||||
// S: * nnnn3 FETCH (UID uuuu3)
|
||||
// S: . OK UID FETCH completed
|
||||
|
||||
// Prepare command and arguments
|
||||
std::ostringstream cmd;
|
||||
cmd.imbue(std::locale::classic());
|
||||
std::vector <string> params;
|
||||
params.push_back("UID");
|
||||
|
||||
cmd << "UID FETCH " << IMAPUtils::messageSetToSequenceSet(msgs) << " UID";
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, cmd.str(), true);
|
||||
IMAPCommand::FETCH(msgs, params)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -679,28 +667,22 @@ std::vector <shared_ptr <folder> > IMAPFolder::getFolders(const bool recursive)
|
||||
// S: * LIST (\NoInferiors) "/" foo/bar/zap
|
||||
// S: a005 OK LIST completed
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "LIST ";
|
||||
shared_ptr <IMAPCommand> cmd;
|
||||
|
||||
const string pathString = IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath());
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
oss << IMAPUtils::quoteString(pathString);
|
||||
oss << " *";
|
||||
cmd = IMAPCommand::LIST(pathString, "*");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pathString.empty()) // don't add sep for root folder
|
||||
oss << "\"\"";
|
||||
else
|
||||
oss << IMAPUtils::quoteString(pathString + m_connection->hierarchySeparator());
|
||||
|
||||
oss << " %";
|
||||
cmd = IMAPCommand::LIST
|
||||
(pathString.empty() ? "" : (pathString + m_connection->hierarchySeparator()), "%");
|
||||
}
|
||||
|
||||
m_connection->send(true, oss.str(), true);
|
||||
cmd->send(m_connection);
|
||||
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -783,10 +765,8 @@ void IMAPFolder::fetchMessages(std::vector <shared_ptr <message> >& msg, const f
|
||||
}
|
||||
|
||||
// Send the request
|
||||
const string command = IMAPUtils::buildFetchRequest
|
||||
(m_connection, messageSet::byNumber(list), options);
|
||||
|
||||
m_connection->send(true, command, true);
|
||||
IMAPUtils::buildFetchCommand
|
||||
(m_connection, messageSet::byNumber(list), options)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -881,10 +861,8 @@ std::vector <shared_ptr <message> > IMAPFolder::getAndFetchMessages
|
||||
attribsWithUID.add(fetchAttributes::UID);
|
||||
|
||||
// Send the request
|
||||
const string command = IMAPUtils::buildFetchRequest
|
||||
(m_connection, msgs, attribsWithUID);
|
||||
|
||||
m_connection->send(true, command, true);
|
||||
IMAPUtils::buildFetchCommand
|
||||
(m_connection, msgs, attribsWithUID)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1016,19 +994,11 @@ void IMAPFolder::deleteMessages(const messageSet& msgs)
|
||||
else if (m_mode == MODE_READ_ONLY)
|
||||
throw exceptions::illegal_state("Folder is read-only");
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
if (msgs.isUIDSet())
|
||||
command << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
else
|
||||
command << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
|
||||
command << " +FLAGS (\\Deleted)";
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::STORE(
|
||||
msgs, message::FLAG_MODE_ADD,
|
||||
IMAPUtils::messageFlagList(message::FLAG_DELETED)
|
||||
)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1046,31 +1016,12 @@ void IMAPFolder::deleteMessages(const messageSet& msgs)
|
||||
|
||||
void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const int mode)
|
||||
{
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
if (msgs.isUIDSet())
|
||||
command << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
else
|
||||
command << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case message::FLAG_MODE_ADD: command << " +FLAGS "; break;
|
||||
case message::FLAG_MODE_REMOVE: command << " -FLAGS "; break;
|
||||
default:
|
||||
case message::FLAG_MODE_SET: command << " FLAGS "; break;
|
||||
}
|
||||
|
||||
const string flagList = IMAPUtils::messageFlagList(flags);
|
||||
const std::vector <string> flagList = IMAPUtils::messageFlagList(flags);
|
||||
|
||||
if (!flagList.empty())
|
||||
{
|
||||
command << flagList;
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::STORE(msgs, mode, flagList)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1116,31 +1067,11 @@ messageSet IMAPFolder::addMessage
|
||||
else if (m_mode == MODE_READ_ONLY)
|
||||
throw exceptions::illegal_state("Folder is read-only");
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
command << "APPEND " << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath())) << ' ';
|
||||
|
||||
const string flagList = IMAPUtils::messageFlagList(flags);
|
||||
|
||||
if (flags != -1 && !flagList.empty())
|
||||
{
|
||||
command << flagList;
|
||||
command << ' ';
|
||||
}
|
||||
|
||||
if (date != NULL)
|
||||
{
|
||||
command << IMAPUtils::dateTime(*date);
|
||||
command << ' ';
|
||||
}
|
||||
|
||||
command << '{' << size << '}';
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::APPEND(
|
||||
IMAPUtils::pathToString(m_connection->hierarchySeparator(), getFullPath()),
|
||||
IMAPUtils::messageFlagList(flags), date, size
|
||||
)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1191,7 +1122,7 @@ messageSet IMAPFolder::addMessage
|
||||
progress->progress(current, total);
|
||||
}
|
||||
|
||||
m_connection->send(false, "", true);
|
||||
m_connection->sendRaw(utility::stringUtils::bytesFromString("\r\n"), 2);
|
||||
|
||||
if (progress)
|
||||
progress->stop(total);
|
||||
@ -1230,7 +1161,7 @@ void IMAPFolder::expunge()
|
||||
throw exceptions::illegal_state("Folder is read-only");
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, "EXPUNGE", true);
|
||||
IMAPCommand::EXPUNGE()->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1259,18 +1190,11 @@ void IMAPFolder::rename(const folder::path& newPath)
|
||||
else if (!store->isValidFolderName(newPath.getLastComponent()))
|
||||
throw exceptions::invalid_folder_name();
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
command << "RENAME ";
|
||||
command << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath())) << " ";
|
||||
command << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), newPath));
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::RENAME(
|
||||
IMAPUtils::pathToString(m_connection->hierarchySeparator(), getFullPath()),
|
||||
IMAPUtils::pathToString(m_connection->hierarchySeparator(), newPath)
|
||||
)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1327,16 +1251,11 @@ messageSet IMAPFolder::copyMessages(const folder::path& dest, const messageSet&
|
||||
else if (!isOpen())
|
||||
throw exceptions::illegal_state("Folder not open");
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
command << "COPY " << IMAPUtils::messageSetToSequenceSet(set) << " ";
|
||||
command << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), dest));
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::COPY(
|
||||
set,
|
||||
IMAPUtils::pathToString(m_connection->hierarchySeparator(), dest)
|
||||
)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1379,24 +1298,22 @@ shared_ptr <folderStatus> IMAPFolder::getStatus()
|
||||
if (!store)
|
||||
throw exceptions::illegal_state("Store disconnected");
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
// Build the attributes list
|
||||
std::vector <string> attribs;
|
||||
|
||||
command << "STATUS ";
|
||||
command << IMAPUtils::quoteString(IMAPUtils::pathToString
|
||||
(m_connection->hierarchySeparator(), getFullPath()));
|
||||
command << " (";
|
||||
|
||||
command << "MESSAGES" << ' ' << "UNSEEN" << ' ' << "UIDNEXT" << ' ' << "UIDVALIDITY";
|
||||
attribs.push_back("MESSAGES");
|
||||
attribs.push_back("UNSEEN");
|
||||
attribs.push_back("UIDNEXT");
|
||||
attribs.push_back("UIDVALIDITY");
|
||||
|
||||
if (m_connection->hasCapability("CONDSTORE"))
|
||||
command << ' ' << "HIGHESTMODSEQ";
|
||||
|
||||
command << ")";
|
||||
attribs.push_back("HIGHESTMODSEQ");
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::STATUS(
|
||||
IMAPUtils::pathToString(m_connection->hierarchySeparator(), getFullPath()),
|
||||
attribs
|
||||
)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1443,7 +1360,7 @@ void IMAPFolder::noop()
|
||||
if (!store)
|
||||
throw exceptions::illegal_state("Store disconnected");
|
||||
|
||||
m_connection->send(true, "NOOP", true);
|
||||
IMAPCommand::NOOP()->send(m_connection);
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
|
||||
@ -1459,15 +1376,15 @@ void IMAPFolder::noop()
|
||||
|
||||
std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid& uid)
|
||||
{
|
||||
std::vector<int> v;
|
||||
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
command << "SEARCH UID " << uid << ":*";
|
||||
|
||||
// Send the request
|
||||
m_connection->send(true, command.str(), true);
|
||||
std::ostringstream uidSearchKey;
|
||||
uidSearchKey.imbue(std::locale::classic());
|
||||
uidSearchKey << "UID " << uid << ":*";
|
||||
|
||||
std::vector <string> searchKeys;
|
||||
searchKeys.push_back(uidSearchKey.str());
|
||||
|
||||
IMAPCommand::SEARCH(searchKeys, /* charset */ NULL)->send(m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
@ -1480,6 +1397,7 @@ std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid&
|
||||
}
|
||||
|
||||
const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data();
|
||||
std::vector <int> seqNumbers;
|
||||
|
||||
for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
|
||||
it = respDataList.begin() ; it != respDataList.end() ; ++it)
|
||||
@ -1505,13 +1423,13 @@ std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid&
|
||||
it != mailboxData->search_nz_number_list().end();
|
||||
++it)
|
||||
{
|
||||
v.push_back((*it)->value());
|
||||
seqNumbers.push_back((*it)->value());
|
||||
}
|
||||
}
|
||||
|
||||
processStatusUpdate(resp.get());
|
||||
|
||||
return v;
|
||||
return seqNumbers;
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,15 +299,7 @@ void IMAPMessage::extractImpl
|
||||
}
|
||||
}
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
if (m_uid.empty())
|
||||
command << "FETCH " << m_num << " BODY";
|
||||
else
|
||||
command << "UID FETCH " << m_uid << " BODY";
|
||||
|
||||
// Build the body descriptor for FETCH
|
||||
/*
|
||||
BODY[] header + body
|
||||
BODY.PEEK[] header + body (peek)
|
||||
@ -316,43 +308,53 @@ void IMAPMessage::extractImpl
|
||||
BODY[TEXT] body
|
||||
BODY.PEEK[TEXT] body (peek)
|
||||
*/
|
||||
std::ostringstream bodyDesc;
|
||||
bodyDesc.imbue(std::locale::classic());
|
||||
|
||||
bodyDesc << "BODY";
|
||||
|
||||
if (extractFlags & EXTRACT_PEEK)
|
||||
command << ".PEEK";
|
||||
bodyDesc << ".PEEK";
|
||||
|
||||
command << "[";
|
||||
bodyDesc << "[";
|
||||
|
||||
if (section.str().empty())
|
||||
{
|
||||
// header + body
|
||||
if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY))
|
||||
command << "";
|
||||
bodyDesc << "";
|
||||
// body only
|
||||
else if (extractFlags & EXTRACT_BODY)
|
||||
command << "TEXT";
|
||||
bodyDesc << "TEXT";
|
||||
// header only
|
||||
else if (extractFlags & EXTRACT_HEADER)
|
||||
command << "HEADER";
|
||||
bodyDesc << "HEADER";
|
||||
}
|
||||
else
|
||||
{
|
||||
command << section.str();
|
||||
bodyDesc << section.str();
|
||||
|
||||
// header + body
|
||||
if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY))
|
||||
throw exceptions::operation_not_supported();
|
||||
// header only
|
||||
else if (extractFlags & EXTRACT_HEADER)
|
||||
command << ".MIME"; // "MIME" not "HEADER" for parts
|
||||
bodyDesc << ".MIME"; // "MIME" not "HEADER" for parts
|
||||
}
|
||||
|
||||
command << "]";
|
||||
bodyDesc << "]";
|
||||
|
||||
if (start != 0 || length != static_cast <size_t>(-1))
|
||||
command << "<" << start << "." << length << ">";
|
||||
bodyDesc << "<" << start << "." << length << ">";
|
||||
|
||||
std::vector <std::string> fetchParams;
|
||||
fetchParams.push_back(bodyDesc.str());
|
||||
|
||||
// Send the request
|
||||
constCast <IMAPFolder>(folder)->m_connection->send(true, command.str(), true);
|
||||
IMAPCommand::FETCH(
|
||||
m_uid.empty() ? messageSet::byNumber(m_num) : messageSet::byUID(m_uid),
|
||||
fetchParams
|
||||
)->send(constCast <IMAPFolder>(folder)->m_connection);
|
||||
|
||||
// Get the response
|
||||
std::auto_ptr <IMAPParser::response> resp
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "vmime/net/imap/IMAPFolder.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPFolderStatus.hpp"
|
||||
#include "vmime/net/imap/IMAPCommand.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/platform.hpp"
|
||||
@ -192,7 +193,7 @@ void IMAPStore::noop()
|
||||
if (!isConnected())
|
||||
throw exceptions::not_connected();
|
||||
|
||||
m_connection->send(true, "NOOP", true);
|
||||
IMAPCommand::NOOP()->send(m_connection);
|
||||
|
||||
std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
|
||||
|
||||
|
@ -488,35 +488,21 @@ int IMAPUtils::messageFlagsFromFlags(const IMAPParser::flag_list* list)
|
||||
}
|
||||
|
||||
|
||||
const string IMAPUtils::messageFlagList(const int flags)
|
||||
// static
|
||||
const std::vector <string> IMAPUtils::messageFlagList(const int flags)
|
||||
{
|
||||
std::vector <string> flagList;
|
||||
|
||||
if (flags == -1)
|
||||
return flagList; // default flags
|
||||
|
||||
if (flags & message::FLAG_REPLIED) flagList.push_back("\\Answered");
|
||||
if (flags & message::FLAG_MARKED) flagList.push_back("\\Flagged");
|
||||
if (flags & message::FLAG_DELETED) flagList.push_back("\\Deleted");
|
||||
if (flags & message::FLAG_SEEN) flagList.push_back("\\Seen");
|
||||
if (flags & message::FLAG_DRAFT) flagList.push_back("\\Draft");
|
||||
|
||||
if (!flagList.empty())
|
||||
{
|
||||
std::ostringstream res;
|
||||
res.imbue(std::locale::classic());
|
||||
|
||||
res << "(";
|
||||
|
||||
if (flagList.size() >= 2)
|
||||
{
|
||||
std::copy(flagList.begin(), flagList.end() - 1,
|
||||
std::ostream_iterator <string>(res, " "));
|
||||
}
|
||||
|
||||
res << *(flagList.end() - 1) << ")";
|
||||
|
||||
return (res.str());
|
||||
}
|
||||
|
||||
return "";
|
||||
return flagList;
|
||||
}
|
||||
|
||||
|
||||
@ -590,7 +576,7 @@ const string IMAPUtils::dateTime(const vmime::datetime& date)
|
||||
|
||||
|
||||
// static
|
||||
const string IMAPUtils::buildFetchRequest
|
||||
shared_ptr <IMAPCommand> IMAPUtils::buildFetchCommand
|
||||
(shared_ptr <IMAPConnection> cnt, const messageSet& msgs, const fetchAttributes& options)
|
||||
{
|
||||
// Example:
|
||||
@ -659,25 +645,7 @@ const string IMAPUtils::buildFetchRequest
|
||||
}
|
||||
}
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command.imbue(std::locale::classic());
|
||||
|
||||
if (msgs.isUIDSet())
|
||||
command << "UID FETCH " << messageSetToSequenceSet(msgs) << " (";
|
||||
else
|
||||
command << "FETCH " << messageSetToSequenceSet(msgs) << " (";
|
||||
|
||||
for (std::vector <string>::const_iterator it = items.begin() ;
|
||||
it != items.end() ; ++it)
|
||||
{
|
||||
if (it != items.begin()) command << " ";
|
||||
command << *it;
|
||||
}
|
||||
|
||||
command << ")";
|
||||
|
||||
return command.str();
|
||||
return IMAPCommand::FETCH(msgs, items);
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "vmime/net/message.hpp"
|
||||
#include "vmime/net/imap/IMAPParser.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPCommand.hpp"
|
||||
|
||||
#include "vmime/mailboxList.hpp"
|
||||
|
||||
@ -79,7 +80,7 @@ public:
|
||||
|
||||
static int messageFlagsFromFlags(const IMAPParser::flag_list* list);
|
||||
|
||||
static const string messageFlagList(const int flags);
|
||||
static const std::vector <string> messageFlagList(const int flags);
|
||||
|
||||
/** Format a date/time to IMAP date/time format.
|
||||
*
|
||||
@ -96,7 +97,7 @@ public:
|
||||
* @param options fetch options
|
||||
* @return fetch request
|
||||
*/
|
||||
static const string buildFetchRequest
|
||||
static shared_ptr <IMAPCommand> buildFetchCommand
|
||||
(shared_ptr <IMAPConnection> cnt, const messageSet& msgs, const fetchAttributes& options);
|
||||
|
||||
/** Convert a parser-style address list to a mailbox list.
|
||||
|
@ -53,6 +53,26 @@ public:
|
||||
return string(reinterpret_cast <const char*>(data), count);
|
||||
}
|
||||
|
||||
/** Casts a string to bytes.
|
||||
*
|
||||
* @param str string
|
||||
* @return pointer to the first byte of the string
|
||||
*/
|
||||
static const byte_t* bytesFromString(const string& str)
|
||||
{
|
||||
return reinterpret_cast <const byte_t*>(str.data());
|
||||
}
|
||||
|
||||
/** Casts a NULL-terminated string to bytes.
|
||||
*
|
||||
* @param str string
|
||||
* @return pointer to the first byte of the string
|
||||
*/
|
||||
static const byte_t* bytesFromString(const char* str)
|
||||
{
|
||||
return reinterpret_cast <const byte_t*>(str);
|
||||
}
|
||||
|
||||
/** Appends bytes to a string.
|
||||
*
|
||||
* @param str string to which append data
|
||||
|
484
tests/net/imap/IMAPCommandTest.cpp
Normal file
484
tests/net/imap/IMAPCommandTest.cpp
Normal file
@ -0,0 +1,484 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2014 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "tests/testUtils.hpp"
|
||||
|
||||
#include "vmime/net/imap/IMAPCommand.hpp"
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
|
||||
|
||||
using namespace vmime::net::imap;
|
||||
|
||||
|
||||
VMIME_TEST_SUITE_BEGIN(IMAPCommandTest)
|
||||
|
||||
VMIME_TEST_LIST_BEGIN
|
||||
VMIME_TEST(testCreateCommand)
|
||||
VMIME_TEST(testCreateCommandParams)
|
||||
VMIME_TEST(testLOGIN)
|
||||
VMIME_TEST(testAUTHENTICATE)
|
||||
VMIME_TEST(testAUTHENTICATE_InitialResponse)
|
||||
VMIME_TEST(testLIST)
|
||||
VMIME_TEST(testSELECT)
|
||||
VMIME_TEST(testSTATUS)
|
||||
VMIME_TEST(testCREATE)
|
||||
VMIME_TEST(testDELETE)
|
||||
VMIME_TEST(testRENAME)
|
||||
VMIME_TEST(testFETCH)
|
||||
VMIME_TEST(testSTORE)
|
||||
VMIME_TEST(testAPPEND)
|
||||
VMIME_TEST(testCOPY)
|
||||
VMIME_TEST(testSEARCH)
|
||||
VMIME_TEST(testSTARTTLS)
|
||||
VMIME_TEST(testCAPABILITY)
|
||||
VMIME_TEST(testNOOP)
|
||||
VMIME_TEST(testEXPUNGE)
|
||||
VMIME_TEST(testCLOSE)
|
||||
VMIME_TEST(testLOGOUT)
|
||||
VMIME_TEST(testSend)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
void testCreateCommand()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::createCommand("MY_COMMAND");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "MY_COMMAND", cmd->getText());
|
||||
}
|
||||
|
||||
void testCreateCommandParams()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::createCommand("MY_COMMAND param1 param2");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "MY_COMMAND param1 param2", cmd->getText());
|
||||
}
|
||||
|
||||
void testLOGIN()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::LOGIN("username", "password");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "LOGIN username password", cmd->getText());
|
||||
VASSERT_EQ("Trace Text", "LOGIN <username> <password>", cmd->getTraceText());
|
||||
}
|
||||
|
||||
void testAUTHENTICATE()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::AUTHENTICATE("saslmechanism");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "AUTHENTICATE saslmechanism", cmd->getText());
|
||||
}
|
||||
|
||||
void testAUTHENTICATE_InitialResponse()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::AUTHENTICATE("saslmechanism", "initial-response");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "AUTHENTICATE saslmechanism initial-response", cmd->getText());
|
||||
}
|
||||
|
||||
void testLIST()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::LIST("ref-name", "mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "LIST ref-name mailbox-name", cmd->getText());
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote = IMAPCommand::LIST("ref name", "mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "LIST \"ref name\" mailbox-name", cmdQuote->getText());
|
||||
}
|
||||
|
||||
void testSELECT()
|
||||
{
|
||||
std::vector <vmime::string> params;
|
||||
params.push_back("param-1");
|
||||
params.push_back("param-2");
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdRO = IMAPCommand::SELECT
|
||||
(/* readOnly */ true, "mailbox-name", std::vector <vmime::string>());
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdRO);
|
||||
VASSERT_EQ("Text", "EXAMINE mailbox-name", cmdRO->getText());
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdROQuote = IMAPCommand::SELECT
|
||||
(/* readOnly */ true, "mailbox name", std::vector <vmime::string>());
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdROQuote);
|
||||
VASSERT_EQ("Text", "EXAMINE \"mailbox name\"", cmdROQuote->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdRW = IMAPCommand::SELECT
|
||||
(/* readOnly */ false, "mailbox-name", std::vector <vmime::string>());
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdRW);
|
||||
VASSERT_EQ("Text", "SELECT mailbox-name", cmdRW->getText());
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdRWParams = IMAPCommand::SELECT
|
||||
(/* readOnly */ false, "mailbox-name", params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdRWParams);
|
||||
VASSERT_EQ("Text", "SELECT mailbox-name (param-1 param-2)", cmdRWParams->getText());
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdRWQuote = IMAPCommand::SELECT
|
||||
(/* readOnly */ false, "mailbox name", std::vector <vmime::string>());
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdRWQuote);
|
||||
VASSERT_EQ("Text", "SELECT \"mailbox name\"", cmdRWQuote->getText());
|
||||
}
|
||||
|
||||
void testSTATUS()
|
||||
{
|
||||
std::vector <vmime::string> attribs;
|
||||
attribs.push_back("attrib-1");
|
||||
attribs.push_back("attrib-2");
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmd =
|
||||
IMAPCommand::STATUS("mailbox-name", attribs);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "STATUS mailbox-name (attrib-1 attrib-2)", cmd->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote =
|
||||
IMAPCommand::STATUS("mailbox name", attribs);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "STATUS \"mailbox name\" (attrib-1 attrib-2)", cmdQuote->getText());
|
||||
}
|
||||
|
||||
void testCREATE()
|
||||
{
|
||||
std::vector <vmime::string> params;
|
||||
params.push_back("param-1");
|
||||
params.push_back("param-2");
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmd =
|
||||
IMAPCommand::CREATE("mailbox-name", params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "CREATE mailbox-name (param-1 param-2)", cmd->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote =
|
||||
IMAPCommand::CREATE("mailbox name", params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "CREATE \"mailbox name\" (param-1 param-2)", cmdQuote->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdNoParam =
|
||||
IMAPCommand::CREATE("mailbox-name", std::vector <vmime::string>());
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNoParam);
|
||||
VASSERT_EQ("Text", "CREATE mailbox-name", cmdNoParam->getText());
|
||||
}
|
||||
|
||||
void testDELETE()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd =
|
||||
IMAPCommand::DELETE("mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "DELETE mailbox-name", cmd->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote =
|
||||
IMAPCommand::DELETE("mailbox name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "DELETE \"mailbox name\"", cmdQuote->getText());
|
||||
}
|
||||
|
||||
void testRENAME()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd =
|
||||
IMAPCommand::RENAME("mailbox-name", "new-mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "RENAME mailbox-name new-mailbox-name", cmd->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote =
|
||||
IMAPCommand::RENAME("mailbox name", "new mailbox name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "RENAME \"mailbox name\" \"new mailbox name\"", cmdQuote->getText());
|
||||
}
|
||||
|
||||
void testFETCH()
|
||||
{
|
||||
std::vector <vmime::string> params;
|
||||
params.push_back("param-1");
|
||||
params.push_back("param-2");
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdNum =
|
||||
IMAPCommand::FETCH(vmime::net::messageSet::byNumber(42), params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNum);
|
||||
VASSERT_EQ("Text", "FETCH 42 (param-1 param-2)", cmdNum->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdNums =
|
||||
IMAPCommand::FETCH(vmime::net::messageSet::byNumber(42, 47), params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNums);
|
||||
VASSERT_EQ("Text", "FETCH 42:47 (param-1 param-2)", cmdNums->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdUID =
|
||||
IMAPCommand::FETCH(vmime::net::messageSet::byUID(42), params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdUID);
|
||||
VASSERT_EQ("Text", "UID FETCH 42 (param-1 param-2)", cmdUID->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdUIDs =
|
||||
IMAPCommand::FETCH(vmime::net::messageSet::byUID(42, 47), params);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdUIDs);
|
||||
VASSERT_EQ("Text", "UID FETCH 42:47 (param-1 param-2)", cmdUIDs->getText());
|
||||
}
|
||||
|
||||
void testSTORE()
|
||||
{
|
||||
std::vector <vmime::string> flags;
|
||||
flags.push_back("flag-1");
|
||||
flags.push_back("flag-2");
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdNum = IMAPCommand::STORE
|
||||
(vmime::net::messageSet::byNumber(42), vmime::net::message::FLAG_MODE_SET, flags);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNum);
|
||||
VASSERT_EQ("Text", "STORE 42 FLAGS (flag-1 flag-2)", cmdNum->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdNums = IMAPCommand::STORE
|
||||
(vmime::net::messageSet::byNumber(42, 47), vmime::net::message::FLAG_MODE_SET, flags);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNums);
|
||||
VASSERT_EQ("Text", "STORE 42:47 FLAGS (flag-1 flag-2)", cmdNums->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdUID = IMAPCommand::STORE
|
||||
(vmime::net::messageSet::byUID(42), vmime::net::message::FLAG_MODE_SET, flags);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdUID);
|
||||
VASSERT_EQ("Text", "UID STORE 42 FLAGS (flag-1 flag-2)", cmdUID->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdUIDs = IMAPCommand::STORE
|
||||
(vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_SET, flags);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdUIDs);
|
||||
VASSERT_EQ("Text", "UID STORE 42:47 FLAGS (flag-1 flag-2)", cmdUIDs->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdAdd = IMAPCommand::STORE
|
||||
(vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_ADD, flags);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdAdd);
|
||||
VASSERT_EQ("Text", "UID STORE 42:47 +FLAGS (flag-1 flag-2)", cmdAdd->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdRem = IMAPCommand::STORE
|
||||
(vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_REMOVE, flags);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdRem);
|
||||
VASSERT_EQ("Text", "UID STORE 42:47 -FLAGS (flag-1 flag-2)", cmdRem->getText());
|
||||
}
|
||||
|
||||
void testAPPEND()
|
||||
{
|
||||
std::vector <vmime::string> flags;
|
||||
flags.push_back("flag-1");
|
||||
flags.push_back("flag-2");
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmd =
|
||||
IMAPCommand::APPEND("mailbox-name", flags, /* date */ NULL, 1234);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "APPEND mailbox-name (flag-1 flag-2) {1234}", cmd->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote =
|
||||
IMAPCommand::APPEND("mailbox name", flags, /* date */ NULL, 1234);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "APPEND \"mailbox name\" (flag-1 flag-2) {1234}", cmdQuote->getText());
|
||||
|
||||
|
||||
vmime::datetime date(2014, 3, 15, 23, 11, 47, vmime::datetime::GMT2);
|
||||
vmime::shared_ptr <IMAPCommand> cmdDate =
|
||||
IMAPCommand::APPEND("mailbox name", flags, &date, 1234);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdDate);
|
||||
VASSERT_EQ("Text", "APPEND \"mailbox name\" (flag-1 flag-2) \"15-Mar-2014 23:11:47 +0200\" {1234}", cmdDate->getText());
|
||||
}
|
||||
|
||||
void testCOPY()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmdNum =
|
||||
IMAPCommand::COPY(vmime::net::messageSet::byNumber(42), "mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNum);
|
||||
VASSERT_EQ("Text", "COPY 42 mailbox-name", cmdNum->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdNums =
|
||||
IMAPCommand::COPY(vmime::net::messageSet::byNumber(42, 47), "mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdNums);
|
||||
VASSERT_EQ("Text", "COPY 42:47 mailbox-name", cmdNums->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdUID =
|
||||
IMAPCommand::COPY(vmime::net::messageSet::byUID(42), "mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdUID);
|
||||
VASSERT_EQ("Text", "UID COPY 42 mailbox-name", cmdUID->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdUIDs =
|
||||
IMAPCommand::COPY(vmime::net::messageSet::byUID(42, 47), "mailbox-name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdUIDs);
|
||||
VASSERT_EQ("Text", "UID COPY 42:47 mailbox-name", cmdUIDs->getText());
|
||||
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdQuote =
|
||||
IMAPCommand::COPY(vmime::net::messageSet::byNumber(42, 47), "mailbox name");
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdQuote);
|
||||
VASSERT_EQ("Text", "COPY 42:47 \"mailbox name\"", cmdQuote->getText());
|
||||
}
|
||||
|
||||
void testSEARCH()
|
||||
{
|
||||
std::vector <vmime::string> searchKeys;
|
||||
searchKeys.push_back("search-key-1");
|
||||
searchKeys.push_back("search-key-2");
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmd =
|
||||
IMAPCommand::SEARCH(searchKeys, /* charset */ NULL);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "SEARCH search-key-1 search-key-2", cmd->getText());
|
||||
|
||||
|
||||
vmime::charset cset("test-charset");
|
||||
|
||||
vmime::shared_ptr <IMAPCommand> cmdCset =
|
||||
IMAPCommand::SEARCH(searchKeys, &cset);
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmdCset);
|
||||
VASSERT_EQ("Text", "SEARCH CHARSET test-charset search-key-1 search-key-2", cmdCset->getText());
|
||||
}
|
||||
|
||||
void testSTARTTLS()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::STARTTLS();
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "STARTTLS", cmd->getText());
|
||||
}
|
||||
|
||||
void testCAPABILITY()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::CAPABILITY();
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "CAPABILITY", cmd->getText());
|
||||
}
|
||||
|
||||
void testNOOP()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::NOOP();
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "NOOP", cmd->getText());
|
||||
}
|
||||
|
||||
void testEXPUNGE()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::EXPUNGE();
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "EXPUNGE", cmd->getText());
|
||||
}
|
||||
|
||||
void testCLOSE()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::CLOSE();
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "CLOSE", cmd->getText());
|
||||
}
|
||||
|
||||
void testLOGOUT()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::LOGOUT();
|
||||
|
||||
VASSERT_NOT_NULL("Not null", cmd);
|
||||
VASSERT_EQ("Text", "LOGOUT", cmd->getText());
|
||||
}
|
||||
|
||||
void testSend()
|
||||
{
|
||||
vmime::shared_ptr <IMAPCommand> cmd = IMAPCommand::createCommand("MY_COMMAND param1 param2");
|
||||
|
||||
vmime::shared_ptr <vmime::net::session> sess =
|
||||
vmime::make_shared <vmime::net::session>();
|
||||
|
||||
vmime::shared_ptr <vmime::security::authenticator> auth =
|
||||
vmime::make_shared <vmime::security::defaultAuthenticator>();
|
||||
|
||||
vmime::shared_ptr <IMAPStore> store =
|
||||
vmime::make_shared <IMAPStore>(sess, auth, /* secured */ false);
|
||||
|
||||
vmime::shared_ptr <IMAPConnection> conn =
|
||||
vmime::make_shared <IMAPConnection>(store, auth);
|
||||
|
||||
vmime::shared_ptr <testSocket> sok = vmime::make_shared <testSocket>();
|
||||
conn->setSocket(sok);
|
||||
|
||||
cmd->send(conn);
|
||||
|
||||
vmime::string response;
|
||||
sok->localReceive(response);
|
||||
|
||||
VASSERT_EQ("Sent buffer", vmime::string(*conn->getTag()) + " MY_COMMAND param1 param2\r\n", response);
|
||||
}
|
||||
|
||||
VMIME_TEST_SUITE_END
|
Loading…
Reference in New Issue
Block a user