diff options
| -rw-r--r-- | src/plugins/messageservices/imap/imapclient.cpp | 31 | ||||
| -rw-r--r-- | src/plugins/messageservices/imap/imapprotocol.cpp | 35 | ||||
| -rw-r--r-- | src/plugins/messageservices/imap/imapprotocol.h | 8 |
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; }; |
