2013年3月15日 星期五

關於 Thunderbird 在 IMAP 上使用郵件篩選中的自訂標頭的問題

過去一直很困擾這個問題,不過今天找到了一些解決方法,在此記錄一下。

首先來看 thunderbird-17.0.4+build1/mailnews/imap/src/nsImapProtocol.cpp 中的一段程式碼

// read in the accept languages preference
if (prefBranch)
{
  if (!gInitialized)
    GlobalInitialization(prefBranch);

  nsCOMPtr prefString;
  prefBranch->GetComplexValue("intl.accept_languages",
                              NS_GET_IID(nsIPrefLocalizedString),
                              getter_AddRefs(prefString));
  if (prefString)
    prefString->ToString(getter_Copies(mAcceptLanguages));

  nsCString customDBHeaders;
  prefBranch->GetCharPref("mailnews.customDBHeaders",
                          getter_Copies(customDBHeaders));

  ParseString(customDBHeaders, ' ', mCustomDBHeaders);                             
  prefBranch->GetBoolPref("mailnews.display.prefer_plaintext", &m_preferPlainText);
}

這段程式碼裡面使用的是 mailnews.customDBHeaders 但是在使用自訂標頭後是卻是儲存在 mailnews.customHeaders

然後再看一下同一個檔案中的另外一段程式碼

if (!downloadAllHeaders)  // if it's ok -- no filters on any header, etc.
{                                                                                        
  char *headersToDL = nullptr;
  char *what = nullptr;
  const char *dbHeaders = (gUseEnvelopeCmd) ? IMAP_DB_HEADERS : IMAP_ENV_AND_DB_HEADERS;
  nsCString arbitraryHeaders;
  GetArbitraryHeadersToDownload(arbitraryHeaders);
  for (uint32_t i = 0; i < mCustomDBHeaders.Length(); i++)
  {
    if (arbitraryHeaders.Find(mCustomDBHeaders[i], CaseInsensitiveCompare) == kNotFound)
    {
      if (!arbitraryHeaders.IsEmpty())
        arbitraryHeaders.Append(' ');
      arbitraryHeaders.Append(mCustomDBHeaders[i]);
    }
  }
  if (arbitraryHeaders.IsEmpty())
    headersToDL = strdup(dbHeaders);
  else
    headersToDL = PR_smprintf("%s %s",dbHeaders, arbitraryHeaders.get());

  if (gUseEnvelopeCmd)
    what = PR_smprintf(" ENVELOPE BODY.PEEK[HEADER.FIELDS (%s)])", headersToDL);
  else
    what = PR_smprintf(" BODY.PEEK[HEADER.FIELDS (%s)])",headersToDL);
  NS_Free(headersToDL);
  if (what)
  {
    commandString.Append(" %s (UID ");
     if (m_isGmailServer)
      commandString.Append("X-GM-MSGID X-GM-THRID X-GM-LABELS ");
    if (aolImapServer)
      commandString.Append(" XAOL.SIZE") ;
    else
      commandString.Append("RFC822.SIZE");
    commandString.Append(" FLAGS");
    commandString.Append(what);
    PR_Free(what);
  }
  else
  {
    commandString.Append(" %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
  }
}

搭配前一段程式碼一起來看,應該是使用空白當分隔符號來進行不分大小寫的比對,於是我就手動將 mailnews.customHeaders 的內容複製到 mailnews.customDBHeaders 裡面並且去掉了冒號,接著重新啟動 Thunderbird 了。

不過卻發現收件匣當中的郵件還是無法篩選到,於是就注意到前面第二段程式碼最前面的 downloadAllHeaders,想說會不會是因為 IMAP 的關係,之前已經儲存在本地端的郵件的 DB 並沒有儲存這些資訊,應該要設法再讓 Thunderbird 重新抓取郵件的標頭, 於是我就將郵件移往其它的目錄再做篩選,果然就可以正常運作了。

另外我找到了一個似乎有相關的修正 Bug 363238 - saved searches fail for searches on x-headers, r=irving,只是目前它並不存在 Thunderbird 裡面就是了。

張貼留言