summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/messageservices/imap/imapclient.cpp31
-rw-r--r--src/plugins/messageservices/imap/imapprotocol.cpp35
-rw-r--r--src/plugins/messageservices/imap/imapprotocol.h8
3 files changed, 69 insertions, 5 deletions
diff --git a/src/plugins/messageservices/imap/imapclient.cpp b/src/plugins/messageservices/imap/imapclient.cpp
index 1a48379b..ac386817 100644
--- a/src/plugins/messageservices/imap/imapclient.cpp
+++ b/src/plugins/messageservices/imap/imapclient.cpp
@@ -314,6 +314,12 @@ void IdleProtocol::idleCommandTransition(const ImapCommand command, const Operat
switch( command ) {
case IMAP_Init:
{
+ if (receivedCapabilities()) {
+ // Already received capabilities in unsolicited response, no need to request them again
+ setReceivedCapabilities(false);
+ idleCommandTransition(IMAP_Capability, status);
+ return;
+ }
// We need to request the capabilities
sendCapability();
return;
@@ -580,7 +586,11 @@ void ImapClient::commandTransition(ImapCommand command, OperationStatus status)
switch( command ) {
case IMAP_Init:
{
- // We need to request the capabilities
+ // We need to request the capabilities. Even in the case that an unsolicited response
+ // has been received, as some servers report incomplete info in unsolicited responses,
+ // missing the IDLE capability.
+ // Currently idle connections must be established before main connection will
+ // service requests.
emit updateStatus( tr("Checking capabilities" ) );
_protocol.sendCapability();
break;
@@ -588,6 +598,14 @@ void ImapClient::commandTransition(ImapCommand command, OperationStatus status)
case IMAP_Capability:
{
+ if (_protocol.authenticated()) {
+ // Received capabilities after logging in, continue with post login process
+ Q_ASSERT(_protocol.receivedCapabilities());
+ _protocol.setReceivedCapabilities(true);
+ commandTransition(IMAP_Login, status);
+ return;
+ }
+
if (!_protocol.encrypted()) {
if (ImapAuthenticator::useEncryption(_config.serviceConfiguration("imap4"), _protocol.capabilities())) {
// Switch to encrypted mode
@@ -637,11 +655,16 @@ void ImapClient::commandTransition(ImapCommand command, OperationStatus status)
case IMAP_Login:
{
- // Once we have logged in, we now have the full set of capabilities (either from
- // a capability command or from an untagged response)
+ // After logging in server capabilities reported may change so we need to request
+ // capabilities again, unless already received in an unsolicited response
+ if (!_protocol.receivedCapabilities()) {
+ emit updateStatus( tr("Checking capabilities" ) );
+ _protocol.sendCapability();
+ return;
+ }
// Now that we know the capabilities, check for Reference support
- bool supportsReferences(_protocol.capabilities().contains("URLAUTH"));
+ bool supportsReferences(_protocol.capabilities().contains("URLAUTH", Qt::CaseInsensitive));
QMailAccount account(_config.id());
ImapConfiguration imapCfg(_config);
diff --git a/src/plugins/messageservices/imap/imapprotocol.cpp b/src/plugins/messageservices/imap/imapprotocol.cpp
index 62e1cdef..b80a2b78 100644
--- a/src/plugins/messageservices/imap/imapprotocol.cpp
+++ b/src/plugins/messageservices/imap/imapprotocol.cpp
@@ -417,6 +417,9 @@ void ImapState::untaggedResponse(ImapContext *c, const QString &line)
QString temp = token(line, '[', ']', &start);
QStringList capabilities = temp.mid(12).trimmed().split(' ', QString::SkipEmptyParts);
c->protocol()->setCapabilities(capabilities);
+ } else if (line.indexOf("* CAPABILITY ", 0) != -1) {
+ QStringList capabilities = line.mid(13).trimmed().split(' ', QString::SkipEmptyParts);
+ c->protocol()->setCapabilities(capabilities);
}
c->buffer().append(line);
@@ -615,6 +618,7 @@ void LoginState::taggedResponse(ImapContext *c, const QString &line)
c->protocol()->setCapabilities(capabilities);
}
+ c->protocol()->setAuthenticated(true);
ImapState::taggedResponse(c, line);
}
@@ -638,6 +642,7 @@ QString LogoutState::transmit(ImapContext *c)
void LogoutState::taggedResponse(ImapContext *c, const QString &line)
{
if (status() == OpOk) {
+ c->protocol()->setAuthenticated(false);
c->protocol()->close();
c->operationCompleted(command(), OpOk);
} else {
@@ -2685,7 +2690,9 @@ ImapProtocol::ImapProtocol()
_transport(0),
_literalDataRemaining(0),
_flatHierarchy(false),
- _delimiter(0)
+ _delimiter(0),
+ _authenticated(false),
+ _receivedCapabilities(false)
{
connect(&_incomingDataTimer, SIGNAL(timeout()), this, SLOT(incomingData()));
connect(&_fsm->listState, SIGNAL(mailboxListed(QString, QString)),
@@ -2736,6 +2743,8 @@ bool ImapProtocol::open( const ImapConfiguration& config )
_precedingLiteral.clear();
_mailbox = ImapMailboxProperties();
+ _authenticated = false;
+ _receivedCapabilities = false;
if (!_transport) {
_transport = new ImapTransport("IMAP");
@@ -2763,6 +2772,8 @@ void ImapProtocol::close()
_fsm->reset();
_mailbox = ImapMailboxProperties();
+ _authenticated = false;
+ _receivedCapabilities = false;
}
bool ImapProtocol::connected() const
@@ -2805,6 +2816,27 @@ void ImapProtocol::setDelimiter(QChar delimiter)
_delimiter = delimiter;
}
+bool ImapProtocol::authenticated() const
+{
+ return _authenticated;
+}
+
+void ImapProtocol::setAuthenticated(bool auth)
+{
+ _authenticated = auth;
+}
+
+// capabilities info has been sent by server, possibly as a result of unsolicited response.
+bool ImapProtocol::receivedCapabilities() const
+{
+ return _receivedCapabilities;
+}
+
+void ImapProtocol::setReceivedCapabilities(bool received)
+{
+ _receivedCapabilities = received;
+}
+
bool ImapProtocol::loggingOut() const
{
return _fsm->state() == &_fsm->logoutState;
@@ -2817,6 +2849,7 @@ const QStringList &ImapProtocol::capabilities() const
void ImapProtocol::setCapabilities(const QStringList &newCapabilities)
{
+ setReceivedCapabilities(true);
_capabilities = newCapabilities;
}
diff --git a/src/plugins/messageservices/imap/imapprotocol.h b/src/plugins/messageservices/imap/imapprotocol.h
index 80740cd3..454781c7 100644
--- a/src/plugins/messageservices/imap/imapprotocol.h
+++ b/src/plugins/messageservices/imap/imapprotocol.h
@@ -159,6 +159,12 @@ public:
QChar delimiter() const;
void setDelimiter(QChar delimiter);
+ bool authenticated() const;
+ void setAuthenticated(bool auth);
+
+ bool receivedCapabilities() const;
+ void setReceivedCapabilities(bool received);
+
QString lastError() const { return _lastError; };
const QStringList &capabilities() const;
@@ -299,6 +305,8 @@ private:
QTimer _incomingDataTimer;
bool _flatHierarchy;
QChar _delimiter;
+ bool _authenticated;
+ bool _receivedCapabilities;
static const int MAX_LINES = 30;
};