【问题标题】:IMAP "search header" command failing when search-text contains exclamation mark (!), ampersand (&), etc当搜索文本包含感叹号 (!)、与号 (&) 等时,IMAP“搜索标头”命令失败
【发布时间】:2012-03-24 06:41:21
【问题描述】:

我正在通过 python 访问 GMail 的 IMAP 接口。我运行这样的命令:

UID SEARCH HEADER Message-ID "abcdef@abc.com"

成功(返回匹配消息的 1 个 UID,如果不存在则返回 0)。但是,如果搜索文本包含某些字符(如 & 或 !),则搜索文本在该点被截断。这意味着:

UID SEARCH HEADER Message-ID "!abcdef@abc.com"

被视为相同

UID SEARCH HEADER Message-ID ""

还有:

UID SEARCH HEADER Message-ID "abc!def@abc.com"

被视为:

UID SEARCH HEADER Message-ID "abc"

我浏览了 IMAP 语言规范,从 ABNF 语言规范看来,这些字符应该是有效的。为什么 gmail 会在“!”处截断这些搜索短语和“&”字符?有没有办法摆脱它们? (我试过了!,作为编码错误的字符串失败)。是否有 RFC 或文档显示真正应该接受的内容?这是 gmail 的 imap 实现中的错误吗?

我也尝试过文字格式,结果相同:

UID SEARCH HEADER Message-ID {15}
abc!def@abc.com

仍被视为:

UID SEARCH HEADER Message-ID {3}
abc

谢谢!

IMAP RFC3501 搜索命令:https://www.rfc-editor.org/rfc/rfc3501#section-6.4.4 正式语法:https://www.rfc-editor.org/rfc/rfc3501#section-9

【问题讨论】:

  • 我可以确认在搜索查询中使用感叹号并没有什么特别之处。您很可能在 gmail 中发现了一个错误。我建议在开发过程中使用几种不同的 IMAP 服务器,特别是因为 gmail 的 IMAP 实现并不以符合 IMAP 规范而闻名。
  • 谢谢诺西德。不幸的是,我需要与此代码一起使用的 IMAP 服务器是 gmail,因此在其他人身上进行测试对解决此错误没有帮助。但很高兴知道我没有读错规范。我会尝试找到一种方法将这个错误报告给谷歌。
  • 是的,我目前在通过 alpine 邮件客户端在 Gmail 上执行 IMAP 搜索时遇到此问题,尝试选择主题包含 ! 的所有邮件。
  • 我还想问:如何克服 GMail 中的这个错误并进行此类搜索?
  • Google 的 IMAP 搜索将事物分解为“单词”,这可能就是特殊字符被奇怪对待的原因。我赞同上述小组中的建议:尝试使用 X-GM-RAW 并发送谷歌搜索关键字。

标签: search gmail imap


【解决方案1】:

我的回答主要基于 cmets 中的发现(由 Max)对 GMail 的 SEARCH 实现使用已将文本内容拆分为单词标记的支持数据库而不是存储全文并执行子字符串搜索。

因此,您可以使用我的MailKit 库(这是一个相当低级的 IMAP 库,因此应该很容易将其转换为基本伪代码)在 C# 中与 GMail 一起使用,这是一个可能的解决方法:

// given: text = "abc!abcdef@abc.com"

// split the search text on '!'
var words = text.Split (new char[] { '!' }, StringSplitOptions.RemoveEmptyEntries);

// build a search query...
var query = SearchQuery.HeaderContains ("Message-ID", words[0]);
for (int i = 1; i < words.Count; i++)
    query = query.And (SearchQuery.HeaderContains ("Message-ID", words[i]));

// this will result in a query like this:
// HEADER "Message-ID" "abc" HEADER "Message-ID" "abcdef@abc.com"

// Do the UID SEARCH with the constructed query:
// A001 UID SEARCH HEADER "Message-Id" "abc" HEADER "Message-Id" "abcdef@abc.com"
var uids = mailbox.Search (query);

// Now UID FETCH the ENVELOPE (and UID) for each of the potential matches:
// A002 UID FETCH <uids> (UID ENVELOPE)
var messages = mailbox.Fetch (uids, MessageSummaryItems.UniqueId |
    MessageSummaryItems.Envelope);

// Now perform a manual comparison of the Message-IDs to get only exact matches...
var matches = new UniqueIdSet (SortOrder.Ascending);
foreach (var message in messages) {
    if (message.Envelope.MessageId.Contains (text))
        matches.Add (message.UniqueId);
}

// 'matches' now contains only the set of UIDs that exactly match your search query

【讨论】:

    【解决方案2】:

    几个月来,我自己一直在解决这个问题。

    搜索标题消息 ID

    最终跳过了一些以“

    你有没有从 Google 那里得到关于这个错误的消息?

    非常感谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 2018-05-15
      • 2014-02-17
      • 2013-07-16
      • 1970-01-01
      • 2017-06-11
      • 2011-10-04
      相关资源
      最近更新 更多