Gmail API 返回的文本/纯文本内容编码存在差异



我正在尝试使用GMail API阅读multipart/mixed电子邮件。
目标是将multipart/mixed电子邮件的每个text/plain部分(可能有很多,采用不同的编码(解码为 C# 字符串(即 UTF-16(:

public static string DecodeTextPart(Google.Apis.Gmail.v1.Data.MessagePart part)
{
var content_type_header = part.Headers.FirstOrDefault(h => string.Equals(h.Name, "content-type", StringComparison.OrdinalIgnoreCase));
if (content_type_header == null)
throw new ArgumentException("No content-type header found in the email part");
var content_type = new System.Net.Mime.ContentType(content_type_header.Value);
if (!string.Equals(content_type.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("The part is not text/plain");
return Encoding.GetEncoding(content_type.CharSet).GetString(GetAttachmentBytes(part.Body));
}

GetAttachmentBytes返回从 GMail 使用的 base64url 编码解码的原始附件字节,无需转换。

我发现在许多情况下,这会产生无效的字符串,因为我为附件内容获得的原始字节似乎始终采用 UTF-8,即使同一部分的content-type声明并非如此。

例如,给定电子邮件:

Date: ...
From: ...
Reply-To: ...
Message-ID: ...
To: ...
Subject: Test 1 text file
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----------0E50FC0802A2FCCAA"
------------0E50FC0802A2FCCAA
Content-Type: text/plain; charset=windows-1251
Content-Transfer-Encoding: 8bit

Content test: Cyrillic, Windows-1251 (à, ÿ, æ)
------------0E50FC0802A2FCCAA
Content-Type: TEXT/PLAIN;
name="Irrelevant.txt"
Content-transfer-encoding: base64
Content-Disposition: attachment;
filename="Irrelevant.txt"
VGhpcyBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdXNlZnVsIGluZm9ybWF0aW9u
------------0E50FC0802A2FCCAA--

,我成功地找到了第一部分,上面的代码图它是在System.Net.Mime.ContentType的帮助下charset=windows-1251的,然后.GetString()返回垃圾,因为GetAttachmentBytes返回的实际原始字节对应于 UTF-8 编码,而不是 Windows-1251。

完全相同的情况发生在

Subject: Test 2 text file
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----------0B716C1D8123D8710"
------------0B716C1D8123D8710
Content-Type: text/plain; charset=koi8-r
Content-Transfer-Encoding: 8bit

Content test: Cyrillic, koi-8 (Б, С, Ц)
------------0B716C1D8123D8710
Content-Type: TEXT/PLAIN;
name="Irrelevant.txt"
Content-transfer-encoding: base64
Content-Disposition: attachment;
filename="Irrelevant.txt"
VGhpcyBmaWxlIGRvZXMgbm90IGNvbnRhaW4gdXNlZnVsIGluZm9ybWF0aW9u
------------0B716C1D8123D8710--

请注意,编码名称后面括号中的三个测试字母在两封电子邮件中是相同的,并且在 Unicode 中看起来像(а, я, ж),但由于编码不同,在上面引用的电子邮件正文中(正确(看起来是错误的。

如果我"修复"函数以始终使用Encoding.UTF8而不是GetEncoding(content_type.CharSet),那么它似乎在我迄今为止所做的测试中有效。

同时,GMail 接口在这两种情况下都能正确显示字母,因此它必须使用正确声明的编码正确解析传入的电子邮件。

GMail API 是否将所有文本块重新编码为 UTF-8(包装在 base64url 中(,但报告它们的原始charset
因此,我是否应该始终使用带有GMail API的UTF-8而忽略content-typecharset=
还是我的代码有问题?

根据这两个资源:

  • 堆栈溢出:Gmail API 在 JavaScript 中解码邮件
  • GitHub:Google API Python 客户端:无效的消息正文大小

值实际上是转换为 UTF-8 的部分的 base-64编码表示形式。

然而,据我所知,谷歌没有记录这一点。

最新更新