fix handling of stat errors and don't stat noselect folders when checking individual folders for new messsages, r/sr=standard8 bug 581707

This commit is contained in:
David Bienvenu 2010-08-02 11:24:11 -07:00
Родитель 075c127a13
Коммит 4dbf37708a
3 изменённых файлов: 141 добавлений и 17 удалений

Просмотреть файл

@ -2366,7 +2366,7 @@ nsImapIncomingServer::OnStopRunningUrl(nsIURI *url, nsresult exitCode)
}
// if we get an error running the url, it's better
// not to chain the next url.
if (NS_FAILED(exitCode))
if (NS_FAILED(exitCode) && exitCode != NS_MSG_ERROR_IMAP_COMMAND_FAILED)
m_foldersToStat.Clear();
if (m_foldersToStat.Count() > 0)
m_foldersToStat[0]->UpdateStatus(this, nsnull);
@ -2994,19 +2994,20 @@ nsImapIncomingServer::GetNewMessagesForNonInboxFolders(nsIMsgFolder *aFolder,
// or if we are forced to check all folders
PRUint32 flags = 0;
aFolder->GetFlags(&flags);
if ((forceAllFolders &&
!(flags & (nsMsgFolderFlags::Inbox | nsMsgFolderFlags::Trash | nsMsgFolderFlags::Junk |
nsMsgFolderFlags::ImapNoselect | nsMsgFolderFlags::Virtual))) ||
(flags & nsMsgFolderFlags::CheckNew))
nsresult rv;
nsCOMPtr<nsIMsgImapMailFolder> imapFolder = do_QueryInterface(aFolder, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRBool canOpen;
imapFolder->GetCanOpenFolder(&canOpen);
if (canOpen && ((forceAllFolders &&
!(flags & (nsMsgFolderFlags::Inbox | nsMsgFolderFlags::Trash |
nsMsgFolderFlags::Junk | nsMsgFolderFlags::Virtual))) ||
flags & nsMsgFolderFlags::CheckNew))
{
// Get new messages for this folder.
aFolder->SetGettingNewMessages(PR_TRUE);
if (performingBiff)
{
nsCOMPtr<nsIMsgImapMailFolder> imapFolder(do_QueryInterface(aFolder));
if (imapFolder)
imapFolder->SetPerformingBiff(PR_TRUE);
}
imapFolder->SetPerformingBiff(PR_TRUE);
PRBool isOpen = PR_FALSE;
nsCOMPtr <nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID);
if (mailSession && aFolder)
@ -3022,9 +3023,7 @@ nsImapIncomingServer::GetNewMessagesForNonInboxFolders(nsIMsgFolder *aFolder,
}
if (gUseStatus && !isOpen)
{
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(aFolder);
if (imapFolder && !isServer &&
m_foldersToStat.IndexOf(imapFolder) == -1)
if (!isServer && m_foldersToStat.IndexOf(imapFolder) == -1)
m_foldersToStat.AppendObject(imapFolder);
}
else
@ -3033,7 +3032,7 @@ nsImapIncomingServer::GetNewMessagesForNonInboxFolders(nsIMsgFolder *aFolder,
// Loop through all subfolders to get new messages for them.
nsCOMPtr<nsISimpleEnumerator> enumerator;
nsresult rv = aFolder->GetSubFolders(getter_AddRefs(enumerator));
rv = aFolder->GetSubFolders(getter_AddRefs(enumerator));
if (NS_FAILED(rv))
return rv;

Просмотреть файл

@ -0,0 +1,119 @@
// This file tests that checking folders for new mail with STATUS
// doesn't try to STAT noselect folders.
var gServer, gImapServer;
var gIMAPInbox, gIMAPFolder1, gIMAPFolder2;
var gFolder2Mailbox;
load("../../mailnews/resources/messageGenerator.js");
const nsIIOService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
function run_test() {
var daemon = new imapDaemon();
daemon.createMailbox("folder 1", {subscribed : true});
let folder1Mailbox = daemon.getMailbox("folder 1");
folder1Mailbox.flags.push("\\Noselect");
daemon.createMailbox("folder 2", {subscribed : true});
gFolder2Mailbox = daemon.getMailbox("folder 2");
addMessageToFolder(gFolder2Mailbox);
gServer = makeServer(daemon, "");
gImapServer = createLocalIMAPServer();
gImapServer.maximumConnectionsNumber = 1;
loadLocalMailAccount();
// We need an identity so that updateFolder doesn't fail
let acctMgr = Cc["@mozilla.org/messenger/account-manager;1"]
.getService(Ci.nsIMsgAccountManager);
let localAccount = acctMgr.createAccount();
let identity = acctMgr.createIdentity();
localAccount.addIdentity(identity);
localAccount.defaultIdentity = identity;
localAccount.incomingServer = gLocalIncomingServer;
acctMgr.defaultAccount = localAccount;
// Let's also have another account, using the same identity
let imapAccount = acctMgr.createAccount();
imapAccount.addIdentity(identity);
imapAccount.defaultIdentity = identity;
imapAccount.incomingServer = gImapServer;
// Get the folder list...
gImapServer.performExpand(null);
gServer.performTest("SUBSCRIBE");
// pref tuning: one connection only, turn off notifications
let prefBranch = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
// Make sure no biff notifications happen
prefBranch.setBoolPref("mail.biff.play_sound", false);
prefBranch.setBoolPref("mail.biff.show_alert", false);
prefBranch.setBoolPref("mail.biff.show_tray_icon", false);
prefBranch.setBoolPref("mail.biff.animate_dock_icon", false);
let rootFolder = gImapServer.rootFolder;
gIMAPInbox = rootFolder.getFolderWithFlags(Ci.nsMsgFolderFlags.Inbox);
gFolder1 = rootFolder.getChildNamed("folder 1");
gFolder2 = rootFolder.getChildNamed("folder 2");
gFolder1.setFlag(Ci.nsMsgFolderFlags.CheckNew);
gFolder2.setFlag(Ci.nsMsgFolderFlags.CheckNew);
do_test_pending();
// imap fake server's resetTest resets the authentication state - charming.
// So poke the _test member directly.
gServer._test = true;
gIMAPInbox.getNewMessages(null, null);
gServer.performTest("STATUS");
// We want to wait for the STATUS to be really done before we issue
// more STATUS commands, so we do a NOOP on the
// INBOX, and since we only have one connection with the fake server,
// that will essentially serialize things.
gServer._test = true;
gIMAPInbox.updateFolder(null);
gServer.performTest("NOOP");
do_timeout_function(0, testCheckStatError);
}
function testCheckStatError() {
// folder 2 should have been stat'd, but not folder 1. All we can really check
// is that folder 2 was stat'd and that its unread msg count is 1
do_check_eq(gFolder2.getNumUnread(false), 1);
addMessageToFolder(gFolder2Mailbox);
gFolder1.clearFlag(Ci.nsMsgFolderFlags.ImapNoselect);
gServer._test = true;
// we've cleared the ImapNoselect flag, so we will attempt to STAT folder 1,
// which will fail. So we verify that we go on and STAT folder 2, and that
// it picks up the message we added to it above.
gIMAPInbox.getNewMessages(null, null);
gServer.performTest("STATUS");
gServer._test = true;
gServer.performTest("STATUS");
do_timeout_function(0, endTest);
}
function addMessageToFolder(mbox) {
// make a couple messges
let messages = [];
let gMessageGenerator = new MessageGenerator();
messages = messages.concat(gMessageGenerator.makeMessage());
let msgURI =
nsIIOService.newURI("data:text/plain;base64," +
btoa(messages[0].toMessageString()),
null, null);
let message = new imapMessage(msgURI.spec, mbox.uidnext++);
mbox.addMessage(message);
}
function endTest()
{
do_check_eq(gFolder2.getNumUnread(false), 2);
// Clean up the server in preparation
gServer.resetTest();
gImapServer.closeCachedConnections();
gServer.performTest();
gServer.stop();
do_test_finished();
}

Просмотреть файл

@ -750,7 +750,7 @@ IMAP_RFC3501_handler.prototype = {
this._lastCommand = command;
// Are we allowed to execute this command?
if (this._enabledCommands[this._state].indexOf(command) == -1)
return this._tag + " BAD illegal command for current state";
return this._tag + " BAD illegal command for current state " + this._state;
try {
// Format the arguments nicely
@ -1001,8 +1001,11 @@ IMAP_RFC3501_handler.prototype = {
var mbox = this._daemon.getMailbox(args[0]);
if (!mbox || mbox.name == "")
return "NO no such mailbox";
if (mbox._children.length > 0 && "\\Noselect" in mbox.flags)
return "NO cannot delete mailbox";
if (mbox._children.length > 0) {
for (let i = 0; i < mbox.flags.length; i++)
if (mbox.flags[i] == "\\Noselect")
return "NO cannot delete mailbox";
}
this._daemon.deleteMailbox(mbox);
return "OK DELETE completed";
},
@ -1055,6 +1058,9 @@ IMAP_RFC3501_handler.prototype = {
var box = this._daemon.getMailbox(args[0]);
if (!box)
return "NO no such mailbox exists";
for (let i = 0; i < box.flags.length; i++)
if (box.flags[i] == "\\Noselect")
return "NO STATUS not allowed on Noselect folder";
var parts = [];
for each (var status in args[1]) {
var line = status + " ";