Skip to content

Commit

Permalink
imapc: Don't use fetch-fix-broken-mails for OK and NO [SERVERBUG] FET…
Browse files Browse the repository at this point in the history
…CH replies

Hopefully no servers are actually returning OK without returning a FETCH
reply. If they are, maybe we need another workaround..

In any case Yahoo IMAP sometimes loses state and starts returning OK without
FETCH replies to all UID FETCH requests (and BADs to FETCHes). It also may
return NO [UNAVAILABLE] for both permanent and temporary FETCH failures, so
we can't do anything with that.

I added NO [SERVERBUG] because that's what Dovecot responds to temporary
failures. I'm not sure how useful that check is though.
  • Loading branch information
sirainen committed Jan 27, 2016
1 parent c67f6d0 commit 6387343
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
35 changes: 32 additions & 3 deletions src/lib-storage/index/imapc/imapc-mail-fetch.c
Expand Up @@ -10,10 +10,41 @@
#include "imap-arg.h"
#include "imap-date.h"
#include "imap-quote.h"
#include "imap-resp-code.h"
#include "imapc-client.h"
#include "imapc-mail.h"
#include "imapc-storage.h"

static void imapc_mail_set_failure(struct imapc_mail *mail,
const struct imapc_command_reply *reply)
{
struct imapc_mailbox *mbox =
(struct imapc_mailbox *)mail->imail.mail.mail.box;

switch (reply->state) {
case IMAPC_COMMAND_STATE_OK:
break;
case IMAPC_COMMAND_STATE_NO:
if (!IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS)) {
/* fetch-fix-broken-mails feature disabled -
fail any mails with missing replies */
break;
}
if (reply->resp_text_key != NULL &&
strcasecmp(reply->resp_text_key, IMAP_RESP_CODE_SERVERBUG) == 0) {
/* this is a temporary error, retrying should work. */
} else {
/* hopefully this is a permanent failure */
mail->fetch_ignore_if_missing = TRUE;
}
break;
case IMAPC_COMMAND_STATE_BAD:
case IMAPC_COMMAND_STATE_DISCONNECTED:
mail->fetch_failed = TRUE;
break;
}
}

static void
imapc_mail_fetch_callback(const struct imapc_command_reply *reply,
void *context)
Expand All @@ -28,9 +59,7 @@ imapc_mail_fetch_callback(const struct imapc_command_reply *reply,
struct imapc_mail *mail = *mailp;

i_assert(mail->fetch_count > 0);
if (reply->state != IMAPC_COMMAND_STATE_OK &&
reply->state != IMAPC_COMMAND_STATE_NO)
mail->fetch_failed = TRUE;
imapc_mail_set_failure(mail, reply);
if (--mail->fetch_count == 0)
mail->fetching_fields = 0;
pool_unref(&mail->imail.mail.pool);
Expand Down
3 changes: 2 additions & 1 deletion src/lib-storage/index/imapc/imapc-mail.c
Expand Up @@ -61,6 +61,7 @@ static bool imapc_mail_is_expunged(struct mail *_mail)

static int imapc_mail_failed(struct mail *mail, const char *field)
{
struct imapc_mail *imail = (struct imapc_mail *)mail;
struct imapc_mailbox *mbox = (struct imapc_mailbox *)mail->box;
bool fix_broken_mail = FALSE;

Expand All @@ -81,7 +82,7 @@ static int imapc_mail_failed(struct mail *mail, const char *field)
versions failed to return any data for messages in Calendars
mailbox. This seems to be fixed in newer versions.
*/
fix_broken_mail = IMAPC_BOX_HAS_FEATURE(mbox, IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS);
fix_broken_mail = imail->fetch_ignore_if_missing;
mail_storage_set_critical(mail->box->storage,
"imapc: Remote server didn't send %s for UID %u in %s%s",
field, mail->uid, mail->box->vname,
Expand Down
1 change: 1 addition & 0 deletions src/lib-storage/index/imapc/imapc-mail.h
Expand Up @@ -20,6 +20,7 @@ struct imapc_mail {
bool header_fetched;
bool body_fetched;
bool header_list_fetched;
bool fetch_ignore_if_missing;
bool fetch_failed;
};

Expand Down

0 comments on commit 6387343

Please sign in to comment.