谷歌在Gmail中使用哪种协议?(不是IMAP或POP)

26

您可以通过网页界面、Google的Android客户端或使用IMAP访问Gmail。据我所知,网页界面和Android应用程序使用的协议与IMAP完全不同,它们不仅仅是在其上提供的接口。我之所以肯定这一点,是因为Android应用程序可以在不到3秒钟的时间内轻松打开一个包含100万邮件的文件夹。没有普通的IMAP客户端能做到这一点。

所以我的问题是,关于这个秘密协议有哪些已知信息?有没有参考文档?它是否被反向工程了?Google是否批准其使用?

阿尔特的答案提供了一个测试Gmail原始IMAP速度的优秀方法:

$ openssl s_client -host imap.gmail.com -port 993 -crlf 
...
* OK Gimap ready for requests from 12.34.56.78
$ a LOGIN ***@*** ***
a OK
$ c SELECT "[Gmail]/All mail" !!!!
* FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen \*)] Flags permitted.
* OK [UIDVALIDITY 673376278] UIDs valid.
* 1142417 EXISTS
* 0 RECENT
* OK [UIDNEXT 1159771] Predicted next UID.
* OK [HIGHESTMODSEQ 8670601]
c OK [READ-WRITE] [Gmail]/All mail selected. (Success)

我标记的命令,c SELECT "[Gmail]/All mail" 需要约20秒钟才能完成。由于这个时间比我的配置相对较弱的Android手机上的GMail应用启动并加载所有邮件标签所需的6秒钟还要长,即使在清除其缓存后也是如此。网络客户端甚至更快。

除非我漏掉了一些基本东西,否则这证明“超出合理怀疑”的谷歌GMail客户端不使用IMAP,因为您永远不必等待任何SELECT命令超过20秒才能完成。


你确定不是IMAP吗?IMAP不需要下载所有电子邮件才能打开文件夹。因此,它可以为前10封电子邮件下载一些信息,并继续在后台下载其余的信息。 - Victor Ronin
是的。对于庞大的邮箱,IMAP性能会下降。Gmail可以在包含100万封邮件的邮箱中以不到3秒的时间显示最近的50个线程。其他任何IMAP客户端都无法做到这一点。Gmail还有更多关于非IMAP特性的明显迹象,但这不是本问题的重点。 - Björn Lindqvist
我相信你有两个选项来解决这个问题 - 解开他们的客户端或者配置设备通过你的电脑WiFi并检查目标端口是什么。 - Victor Ronin
1
我认为 Gmail 应用程序没有使用 POP 或 IMAP,因为我禁用了这两个选项,但我的 Android 手机仍然可以接收电子邮件。 - Stony
1
稍后:Gmail的REST API已经公开发布:https://developers.google.com/gmail/api/ - Max
4个回答

11

经过更多的研究,我发现有一个Gmail API:https://developers.google.com/gmail/api/。我认为在2013年我发布这个问题时还没有发布这个API。

使用该API,我创建了一个演示程序,可以获取一个标签的最近100封邮件:https://gist.github.com/bjourne/37a9d15b03862003008a1b0169190dbe

程序的相关部分如下:

resource = service.users().messages()
result = resource.list(userId = 'me', labelIds = [label]).execute()
mail_ids = [m['id'] for m in result['messages']]

start = time()
mails = []
batch = BatchHttpRequest()
cb = lambda req, res, exc: mails.append(to_mail(res))
for mail_id in mail_ids:
    get_request = resource.get(**headers_params(mail_id))
    batch.add(get_request, callback = cb)
result = batch.execute()
print('Took %.2f seconds' % (time() - start))

它在一个包含超过570k条消息的标签(IMAP术语中的文件夹)中按日期排序列出了最近100条消息。

在我的机器上,这个循环大约需要0.5-0.8秒。我可以自信地声称,全球没有任何一个纯IMAP客户端可以做到如此之快。很可能,IMAP永远都不会变得更快,因为它与Google内部邮件存储方式不兼容。

所以我会回答自己的问题。这就是他们正在使用的API,并且之前没有公开。


4
这里实际上需要花费时间的工作是MSN的维护。当您访问一条信息时,谷歌的服务器会告诉您它是邮箱中当前第569901封信息。这是大多数IMAP客户端会丢弃的信息。 - arnt

11

安卓应用(至少我使用过的)使用IMAP。你可以在服务器上运行Wireshark来验证这一点。

至于为什么安卓应用如此之快-我所知道的是,它使用SEARCH命令选择最近的n封电子邮件。桌面客户端如Thunderbird或Outlook要重得多,并下载文件夹中每个邮件的头部和元数据,尽管有不建议这样做的建议。

智能手机没有存储和处理数百万封电子邮件的资源(虽然更现代化的可能会做到),因此SEARCH方法允许手持设备快速访问邮件。

无论如何,Wireshark可以揭示IMAP客户端和服务器的行为方式。如果你真的很好奇,试试看吧。如果服务器是Gmail,则无法进行此操作,但可以在另一个服务器(例如hMailServer)上尝试。


我要谈论的Android应用是:https://play.google.com/store/apps/details?id=com.google.android.gm。你怎么知道它使用IMAP?另外,据我所知,在IMAP中没有办法将搜索限制为最近的n封邮件。如果您知道其他情况,请提供参考。因此,那不可能是Gmail快速的原因。 - Björn Lindqvist
我知道这一点,因为我已经广泛使用IMAP - 正如我所说,如果您连接到服务器并在该服务器上运行Wireshark,则会看到消息通过。而且,正如我所说,您可以通过使用SEARCH命令获取一组最近的消息。如果我没记错的话,Android邮件客户端会将SEARCH与日期条件结合使用,以便获取最近两周的邮件之类的内容。再次强调,了解这一点的最佳方法是在Wireshark中亲自查看。 - Gigi
1
如果客户端关注EXISTS消息,它可以搜索最近的n条消息。如果服务器的最后一个EXISTS是50000,则“x UID SEARCH 49000:* SUBJECT sex”在最近的一千封邮件中搜索有关性爱的邮件。 - arnt
还有更多搜索最近消息的方法。对于Gmail,我可能会使用modseq或日期子句。 - arnt
我不记得确切的命令,但据我所知,Android使用SEARCH命令,其中结合了日期(最近2周)和序列号。智能手机的功能相对有限,所以它们通常会检索最近的25或50条消息,然后在您明确请求更多时获取剩余部分。 - Gigi
Android应用程序...使用IMAP - 尽管您从未必须在Gmail帐户中启用IMAP才能使用Gmail Android应用程序?如果您使用任何其他第三方IMAP客户端,那么您必须这样做。 - MrWhite

3
你可以很容易地测试Gmail的IMAP性能(如果你有一个拥有百万封邮件的邮箱)。使用以下命令打开一个IMAP连接:
openssl s_client -connect imap.gmail.com:993 -crlf

然后登录并打开您的收件箱。
a login yourname@gmail.com yourpassword
b select inbox

如果收件箱不够大,请打开您的所有邮件箱(名称可能因UI语言而异):

c select "[Gmail]/All Mail"

如果SELECT很快,但IMAP客户端很慢,则是因为客户端发送了额外/不必要的慢命令。许多人选择为整个million封邮件填充或更新数据结构,即使他们只显示40封邮件。这是客户端的选择,而不是IMAP的慢速。


1
“No other IMAP client can do this”是一个非常大胆的声明,但一百万条信息也是一个相当庞大的数字。我鼓励您在这里尝试Trojitá。由于IMAP标志,SELECTSEARCHSTATUS的相关技术原因,最初的同步可能会相当缓慢(它会传输那一百万条信息的标志),但随后的重新同步应该非常快速,这要归功于ESEARCHCONDSTOREQRESYNC。我很想听听Trojitá在您的设置中的表现 - 联系信息在主页上。

对于您的问题 - 大多数网络邮件现在都为其自身使用提供私有API。典型的架构是通过JSON传递有关更新状态的消息,但没有标准,接口是专有的。GMail“应用程序”很可能使用相同(或类似)的方法。由于它很可能使用TLS,您没有太多选项来验证此内容。使用Web界面,可以使用适当的浏览器插件轻松查看流量,但使用独立的Android应用程序则不太容易。


感谢您的建议。Trojita并不慢(与其他一些客户端相比实际上非常迅速),但其速度远远不及Gmail的本机客户端。 - Björn Lindqvist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接